如何将操作转换为具有相同签名的已定义委托?

发布于 2024-12-11 02:11:28 字数 795 浏览 0 评论 0原文

class Test
{
    public delegate void FruitDelegate(Fruit f);

    public void Notify<T>(Action<T> del) where T : Fruit
    {
        FruitDelegate f = del; // Cannot implicitly convert type 'Action<T>' to 'FruitDelegate
    }
}

水果是一个空类。这两位代表都有相同的签名。

我似乎无法让这些工作发挥作用。如果我解释一下我想要做什么(提供一些背景信息),也许会有帮助。

我想创建一个具有通用静态方法的类,该方法提供类型和方法回调(如上面的示例)。

我遇到的问题是委托包含一个参数,我不想在方法回调中强制转换它。例如,我想要这个:

public void SomeMethod()
{
    Test.Notify<Apple>(AppleHandler);
}

private void AppleHandler(Apple apple)
{

}

而不是这个:

public void SomeMethod()
{
    Test.Notify<Apple>(AppleHandler);
}

private void AppleHandler(Fruit fruit)
{
    Apple apple = (Apple)fruit;
}

这种事情可能吗?

class Test
{
    public delegate void FruitDelegate(Fruit f);

    public void Notify<T>(Action<T> del) where T : Fruit
    {
        FruitDelegate f = del; // Cannot implicitly convert type 'Action<T>' to 'FruitDelegate
    }
}

Fruit is an empty class. Both of these delegates have the same signature.

I cannot seem to get any of this working. Maybe it would help if I explained what I am trying to do (provide some context).

I want to create a class that has a generic static method that provides a type and a method callback (like the above example).

The problem I am having is that the delegate contains a parameter and I don't want to have to cast it within the method callback. For example, I want this:

public void SomeMethod()
{
    Test.Notify<Apple>(AppleHandler);
}

private void AppleHandler(Apple apple)
{

}

Instead of this:

public void SomeMethod()
{
    Test.Notify<Apple>(AppleHandler);
}

private void AppleHandler(Fruit fruit)
{
    Apple apple = (Apple)fruit;
}

Is this kind of thing possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔戏命师 2024-12-18 02:11:28

这是你想要的吗?

static void Main(string[] args)
{

    Program p = new Program();
    p.SomeMethod();
}

public class Fruit
{ }

public class Apple : Fruit { }

public delegate void FruitDelegate<in T>(T f) where T : Fruit;

class Test
{
    public static void Notify<T>(FruitDelegate<T> del)
        where T : Fruit, new()
    {
        T t = new T();
        del.DynamicInvoke(t);
    }
}

private void AppleHandler(Apple apple)
{
    Console.WriteLine(apple.GetType().FullName);
}

public void SomeMethod()
{
    FruitDelegate<Apple> del = new FruitDelegate<Apple>(AppleHandler);
    Test.Notify<Apple>(del);
}

is this what you want?

static void Main(string[] args)
{

    Program p = new Program();
    p.SomeMethod();
}

public class Fruit
{ }

public class Apple : Fruit { }

public delegate void FruitDelegate<in T>(T f) where T : Fruit;

class Test
{
    public static void Notify<T>(FruitDelegate<T> del)
        where T : Fruit, new()
    {
        T t = new T();
        del.DynamicInvoke(t);
    }
}

private void AppleHandler(Apple apple)
{
    Console.WriteLine(apple.GetType().FullName);
}

public void SomeMethod()
{
    FruitDelegate<Apple> del = new FruitDelegate<Apple>(AppleHandler);
    Test.Notify<Apple>(del);
}
烟若柳尘 2024-12-18 02:11:28

您有充分的理由不能这样做。假设你的方法的其余部分是:

class Test
{
    public delegate void FruitDelegate(Fruit f);

    public void Notify<T>(Action<T> del) where T : Fruit
    {
        FruitDelegate f = del; 
        f(new Banana());  //should be legal, but del may be Action<Apple>
    }
}

那肯定行不通,所以编译器在这里是正确的。

There is good reason you cannot do this. Suppose the rest of your method was:

class Test
{
    public delegate void FruitDelegate(Fruit f);

    public void Notify<T>(Action<T> del) where T : Fruit
    {
        FruitDelegate f = del; 
        f(new Banana());  //should be legal, but del may be Action<Apple>
    }
}

That would definitely not work, so the compiler is correct here.

横笛休吹塞上声 2024-12-18 02:11:28

像这样的事情怎么办?

public void Notify<T>(Action<T> del) where T : Fruit
{
    FruitDelegate f = fruit => del((T)fruit);
}

例如,如果使用 Banana 参数调用 AppleHandler,则 FruitDelegate 实例在调用时会抛出 InvalidCastException。

What about something like this?

public void Notify<T>(Action<T> del) where T : Fruit
{
    FruitDelegate f = fruit => del((T)fruit);
}

The FruitDelegate instance, when invoked, would throw an InvalidCastException if, say, an AppleHandler was invoked with a Banana argument.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文