简体   繁体   中英

Restrict Return Type of Generic Delegate Irrespective of Parameters

I'm trying to restrict the return type of a generic delegate without specifying the parameter signature, and I don't know how to do this, or if it is even possible.

How can I do this or is it impossible?

My research has come up dry. Some pseudo-C# code would probably help steer you toward what I'm trying to do:

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();
    }
}

... Elsewhere

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.

I know this is a rather contrived pseudo example. I aim for a more involved usage, of course. I'm trying to write a console menu class that would associate a list of given menu options with actions that would fire depending on what option the user chooses. Right now, it just returns the string the user chose from the menu. What I'd like be able to do is return what--if anything--the associated method returns. This could perhaps be returned with the user chosen option string in a tuple... But, I figured this mini-example just cut straight to the technical hurdle I'm experiencing.

Thanks!

.NET already defines a generic delegate that returns the generic argument as it's result, Func<T> . You don't even need to define it.

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

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

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

There's no real useful reason to allow a user of the type to provide any arbitrary delegate of the same signature. Really I'd advise you to avoid using any delegates in your code other than Func and Action (with various different numbers of generic arguments) whenever possible, as it's just creating a hassle to do so. I would consider it a reasonable restriction on any caller that has a delegate of a different type but the same signature to simply convert it to a Func<T> anyway, it's not like it's even a difficult conversion for them.

If you don't want to use Func<T> (as Servy suggests), eg if you have a custom delegate of your own that you want to be passed with type-safety, then perhaps you can make your custom delegate generic with respect to its return type. Then you can do it this way:

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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM