Как пренебречь DNAStringSet из списка, если длина ≤ 1?

Это работает (в C # 4.0 по крайней мере - не пробовали в более ранних версиях):

SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);

Если вы посмотрите на IL, это скомпилируется в тот же код, что и ответ Winston. Вот IL для второй строки того, что я только что написал:

ldloc.0
ldftn      instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)

И это также то, что вы видите, если назначить a.Invoke на c.

Кстати, хотя решение Диего более эффективно, поскольку полученный делегат ссылается непосредственно на базовый метод, а не на другой делегат, он не обрабатывает делегатов многоадресной рассылки правильно. Решение Winston делает это, потому что оно просто полностью подчиняется другому делегату. Если вам нужно прямое решение, которое также обрабатывает делегатов с несколькими целями, вам нужно что-то более сложное:

public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
    Delegate result = null;
    foreach (Delegate sourceItem in source.GetInvocationList())
    {
        var copy = Delegate.CreateDelegate(
            typeof(TResult), sourceItem.Target, sourceItem.Method);
        result = Delegate.Combine(result, copy);
    }

    return (TResult) (object) result;
}

Это делает правильную вещь для делегатов с одной целью, кстати, - это закончится создавая только один делегат целевого типа, который ссылается непосредственно на любой метод (и, где это применимо, объект), на который ссылается входной делегат.

0
задан Konrad Weber 18 January 2019 в 13:31
поделиться