不受参数限制的通用委托的返回类型

时间:2018-10-31 17:57:20

标签: c# generics delegates

我试图在不指定参数签名的情况下限制泛型委托的返回类型,并且我不知道该怎么做,甚至可能。

我该怎么办?还是不可能?

我的研究干了。一些伪C#代码可能会帮助您引导我去做:

public class SomeClass< T, U > where T : Delegate // returning U
{
    private someDelegate;

    public SomeClass( T someDelegate )
    {
        this.someDelegate = someDelegate;
    }

    public U Run()
    {
        return someDelegate.DynamicInvoke();
    }
}

...在其他地方

public delegate string aDelegate();

public static string SayHi()
{
    return "Hello!";
}

aDelegate greeter = SayHi;

var something = new SomeClass< aDelegate, string>( greeter );

Console.WriteLine( something.Run() ); // Should write "Hello" to the console.

我知道这是一个人为的伪示例。当然,我的目标是更广泛地使用。我正在尝试编写一个控制台菜单类,该类将给定菜单选项的列表与将根据用户选择的选项触发的动作相关联。现在,它仅返回用户从菜单中选择的字符串。我想做的就是返回相关联的方法返回的内容(如果有的话)。也许可以用用户选择的元组中的选项字符串返回它。但是,我认为这个迷你示例正好切入了我所遇到的技术障碍。

谢谢!

2 个答案:

答案 0 :(得分:0)

.NET已经定义了一个通用委托,该委托将返回通用参数Func<T>。您甚至不需要定义它。

public class SomeClass<U>
{
    private Func<U>;

    public SomeClass(Func<U> someDelegate)
    {
        this.someDelegate = someDelegate;
    }

    public U Run()
    {
        return someDelegate();
    }
}

没有真正有用的理由允许该类型的用户提供具有相同签名的任意委托。确实,我建议您尽量避免在代码中使用FuncAction以外的任何委托(带有各种不同数量的通用参数),因为这样做会很麻烦。对于任何具有不同类型的委托但具有相同签名的调用者,无论如何将其简单地转换为Func<T>,我都认为这是一个合理的限制,这对他们来说甚至都不是一个困难的转换。

答案 1 :(得分:-1)

如果您不想使用Func<T>(如Servy建议),例如如果您有自己的自定义委托要通过类型安全传递,则也许可以使自定义委托的返回类型通用。然后,您可以按照以下方式进行操作:

public delegate T MyDelegate<T>();

public class Foo<T>
{
    private readonly MyDelegate<T> _delegate;

    public Foo(MyDelegate<T> handler)
    {
        _delegate = handler;
    }

    public T Bar()
    {
        return _delegate();
    }
}