【问题标题】:How to use an anonymous interface callback method as parameter in C#? [duplicate]如何在 C# 中使用匿名接口回调方法作为参数? [复制]
【发布时间】:2014-01-28 20:31:03
【问题描述】:

在 Java 中,我可以执行以下操作:

Java

public class Button {
    private Callback callback;

    public Button(Callback callback) {
        this.callback = callback;
    }

    public void update() {
        // Check if clicked..
        callback.onClick(this);
    }

    public interface Callback {
        public void onClick(Button Button);
    }
}

并像这样使用它:

Button b = new Button(new Callback() {
    @Override
    public void onClick(Button b) {
        System.out.println("Clicked");
    }
});

我想知道,在 (Unity) C# 中是否也可以这样做。

目前我的设置相同,语法正确

C#:

public class Button {
    private Callback callback;

    public Button(Callback callback) {
        this.callback = callback;
    }

    public void Update() {
        // Check if clicked..
        callback.OnClick(this);
    }

    public interface Callback {
        void OnClick(Button button);
    }
}

但是,当我在创建按钮时尝试这样做时,

Button b = new Button(new Button.Callback() {
    void OnClick(Button button) {
        Debug.Log("Clicked");
    }
});

我收到如下错误:

Unexpected symbol 'void'

error CS1526: A new expression requires () or [] after type

error CS8025: Parsing error

我尝试在界面中将方法设置为“虚拟”或“抽象”,或者在创建按钮时在 void OnClick(.. 之前添加“新”关键字,但到目前为止没有运气。

如果我从“new Button.Callback”中删除“()”,意外的符号“void”错误似乎消失了

我希望能得到一些帮助。

【问题讨论】:

  • 我现在有更多的运气找到答案,我不知道它被称为内联接口。也感谢您的链接。
  • 统一标签适用于 Microsoft Unity。请不要滥用它。

标签: c# java callback unity3d


【解决方案1】:

您尝试做的事情(即匿名接口)在 C# 中是不可能的。但是,您可以使用delegates 来实现类似的效果,

public class Button {
    private Action<Button> action;

    public Button(Action<Button> action) {
        this.action = action;
    }

    public void Update() {
        // Check if clicked..
        action(this);
    }
}

那么,

Button b = new Button(delegate(Button button) { Debug.Log("Clicked"); });

或者使用 lambda 表达式,这样看起来更简单,

Button b = new Button(button => Debug.Log("Clicked"));

Action 基本上是表示函数的泛型类型,特别是返回类型为void 的函数。因此,您可以传入现有方法,只要它们符合签名void Method()。如果您指定任何类型参数(使用 Action&lt;T&gt; 语法),则您正在指定表示的函数接受的参数的数量和类型,因此 Action&lt;Button&gt; 是一个返回 void 并接受 @987654331 类型的单个参数的函数@,就像你的 Callback.OnClick 方法一样。

您可以传入一个符合预期签名的方法,而不是使用匿名委托或 lambda 表达式(例如,如上),

void OnClick(Button button)
{
     Debug.Log("Clicked");
}

并通过它,

 Button b = new Button(OnClick);

【讨论】:

  • Action 是内置类还是处理按钮点击的定制类?
  • 是的,它基本上是一个表示函数的泛型类型,特别是返回类型为void的函数。因此,您可以传入现有方法,只要它们符合签名void Method(Button button)
  • 我搞定了,非常感谢!
  • 没问题;乐意效劳。 =)
【解决方案2】:

您正在寻找Event handlers:

也许你想要这样的东西:

public delegate void Callback(Button btn);
public class Button
{

    public event Callback Click;
    public Button(Callback callback)
    {
        Click += callback;
    }

    public void Update()
    {
        // Check if clicked..
        if (Click != null)
        {
            Click(this);
        }
    }


}

用法:

Button btn = new Button( b => Debug.Log("Clicked"));

【讨论】:

    【解决方案3】:

    我认为你只需要像这样在 final 类中实现你的接口:

    public class SomeClass: Callback
    {
        public SomeClass()
        {
           Button b = new Button(this);
        }
    
    
        void OnClick(Button button)
        {
            Debug.Log("Clicked");
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 2014-12-11
      • 2014-01-10
      • 2012-02-24
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      相关资源
      最近更新 更多