簡體   English   中英

等效於 C# 中的 Java 匿名類?

[英]Equivalent of Java's anonymous class in C#?

我正在嘗試將用 Java 編寫的 SDK 移植到 C#。

在這個軟件中,有許多“處理程序”接口,有幾種方法(例如: attemptSomethingHandlersuccess()和幾種不同的失敗方法)。 然后在調用類中匿名實現和實例化該接口,並傳遞給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 }

然而,這些不能在其中放置方法,只能通過使用objectdynamic傳遞給方法(因為它們在編譯時沒有類型,它們由編譯器 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM