[英]Equivalent of Java's anonymous class in C#?
我正在嘗試將用 Java 編寫的 SDK 移植到 C#。
在這個軟件中,有許多“處理程序”接口,有幾種方法(例如: attemptSomethingHandler
和success()
和幾種不同的失敗方法)。 然后在調用類中匿名實現和實例化該接口,並傳遞給SomethingModel
類的attemptSomething
方法。 這是一個異步方法,有幾個地方可能會失敗或調用另一個方法(傳遞處理程序)。 這樣, attemptSomethingHandler
的匿名實現就可以引用調用attemptSomething
的類中的私有方法。
在 C# 中,不可能匿名實現接口。 我可以顯式地實現一個新類,但是這個實現對於這個調用類來說是唯一的,不用於其他任何東西。 更重要的是,我將無法訪問調用類中的私有方法,而我需要且不想公開這些方法。
基本上,我需要根據SomethingModel
類方法中發生的情況從調用類運行不同的代碼。
我一直在閱讀委托,但這需要傳遞與處理程序接口中的方法一樣多的委托(據我所知)。 在 C# 中執行此操作的適當方法是什么? 我覺得我錯過了一個非常常見的編程策略。 必須有一種簡單、干凈的方法來構建和解決這個問題。
使用委托:
void AttemptSomethingAsync(Action onSuccess, Action<string> onError1, Action onError2 = null) {
// ...
}
// Call it using:
AttemptSomethingAsync(onSuccess: () => { Yes(); }, onError1: (msg) => { OhNo(msg); });
或者,使用類
class AttemptSomethingHandler {
Action OnSuccess;
Action<string> OnError1;
Action OnError2;
}
void AttemptSomethingAsync(AttemptSomethingHandler handler) {
// ...
}
// And you call it like
AttemptSomethingAsync(new AttemptSomethingHandler() {
OnSuccess = () => { Yes() };
});
或活動
public delegate void SuccessHandler();
public delegate void ErrorHandler(string msg);
class SomethingModel {
public event SuccessHandler OnSuccess;
public event ErrorHandler OnError1;
public void AttemptSomethingAsync() {
// ...
}
}
// Use it like
var model = new SomethingModel();
model.OnSuccess += Yes;
model.AttemptSomethingAsync();
private void Yes() {
}
在 C# 中,我們沒有像 Java 本身那樣的匿名類型。 您可以創建一個包含如下字段的匿名類型:
var myObject = new { Foo = "foo", Bar = 1, Quz = 4.2f }
然而,這些不能在其中放置方法,只能通過使用object
或dynamic
傳遞給方法(因為它們在編譯時沒有類型,它們由編譯器 AFAIK 生成)
正如您所說,在 C# 中,我們使用委托或 lambdas。
如果我正確理解你的泡菜,你可以實現一個嵌套的私有類,如下所示:
interface IMyInterface
{
void Foo();
}
class MyClass
{
public void Bar()
{
var obj = new MyInterface();
obj.Foo();
}
private class MyInterface : IMyInterface
{
public void Foo()
{
// stuff
}
}
}
現在MyClass
可以創建一個實例MyInterface
,它實現IMyInterface
。 正如評論者所提到的, MyInterface
可以訪問MyClass
成員(盡管您肯定想嘗試並堅持使用這兩種類型的可公開訪問的成員)。
這種封裝的“匿名”類(使用Java術語在這里,使其更簡單),也意味着你可能會返回MyInterface
作為IMyInterface
和軟件的其余部分將是毫無收獲。 這實際上是一些抽象工廠模式的工作方式。
基本上,我需要根據SomethingModel 類方法中發生的情況從調用類運行不同的代碼。
這聞起來有重耦合的味道。 哦親愛的!
在我看來,您的特定問題可以使用重構。 在 C# 中,您可以使用事件來解決這個問題(注意:可以,不應該)。 只需為您的方法的每個“分支”點設置一個事件。 但是我必須說,這確實使您的解決方案更難設想和維護。
但是,我建議您以一種不需要如此繁重的耦合的方式構建您的解決方案。
您也可以嘗試使用管道模型,但我不確定如何自己實現。 我知道碼頭(或者是 Netty?JBOSS 的 Java 版 NIO)肯定使用了類似的模型。
您可能會發現,為了測試類的預期功能而放棄一些單元測試將使構建解決方案 (TDD) 變得更加容易。
您可以使用嵌套類來模擬匿名類,但為了以與 Java 相同的方式使用嵌套類,您需要傳遞對外部類的引用。 在 Java 中,默認情況下所有嵌套和匿名類都有這個,只有靜態類沒有。
interface IMyInterface
{
void Foo();
}
class MyClass
{
public void Bar()
{
IMyInterface obj = new AnonymousAnalog(this);
obj.Foo();
}
private class AnonymousAnalog : IMyInterface
{
public void Foo(MyClass outerThis)
{
outerThis.privateFieldOnOuter;
outerThis.PrivateMethodOnOuter();
}
}
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.