Ограничить тип возвращаемого значения общего делегата независимо от параметров - PullRequest
0 голосов
/ 31 октября 2018

Я пытаюсь ограничить тип возвращаемого значения универсального делегата без указания сигнатуры параметра, и я не знаю, как это сделать, или если это вообще возможно.

Как я могу это сделать или это невозможно?

Мое исследование провалилось. Некоторый псевдо-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 голосов
/ 31 октября 2018

Если вы не хотите использовать 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();
    }
}
0 голосов
/ 31 октября 2018

.NET уже определяет универсальный делегат, который возвращает универсальный аргумент в качестве результата, Func<T>. Вам даже не нужно это определять.

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

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

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

Нет реальной полезной причины, позволяющей пользователю типа предоставлять любой произвольный делегат с той же подписью. На самом деле, я бы посоветовал вам по возможности избегать использования в вашем коде любых делегатов, кроме Func и Action (с различным количеством общих аргументов), так как это просто создает трудности. Я бы посчитал это разумным ограничением для любого вызывающего абонента, у которого есть делегат другого типа, но с одной и той же сигнатурой, чтобы просто преобразовать его в Func<T> в любом случае, это не похоже на то, что это даже трудное преобразование для них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...