Неявное преобразование в Func - PullRequest
5 голосов
/ 27 мая 2009

Допустим, у меня есть интерфейс IMyInterface<T>, который просто описывает одну функцию:

public interface IMyInterface<T>
{
    T MyFunction(T item);
}

Я мог бы просто заменить это на Func<T, T>, но я хочу интерфейс по семантическим причинам. Могу ли я определить неявное преобразование между этим интерфейсом и Func<T,T> так, чтобы я мог передать анонимный делегат или лямбду в качестве аргумента функции, которая принимает этот интерфейс в качестве параметра, как если бы я использовал Func<T,T> вместо этого?

Чтобы продемонстрировать, используя интерфейс, заявленный выше, я хочу функцию, подобную этой:

public T TestFunction<T>(IMyInterface myInterface, T value)
{
    return myInterface.MyFunction(value);
}

То, что я могу назвать так:

TestFunction<string>( x => return x + " world", "hello");

И результатом будет "Привет, мир".

1 Ответ

3 голосов
/ 27 мая 2009

Поскольку интерфейсы в C # не могут содержать определения операторов (или любых статических методов в этом отношении), я считаю, что ответом является no . Альтернативой является использование класса (к сожалению, не может быть абстрактным, поскольку статические члены / операторы здесь не лучше, чем в интерфейсах). Это позволит вам определить оператор преобразования implicit и, следовательно, сможет использовать тип точно так, как вы указали.

В классе (который вы, возможно, могли бы сделать virtual, если требуется), вы бы определили его примерно так:

public class MyClass<T>
{
    public static implicit operator MyClass<T>(Func<T, T> func)
    {
        return new MyClass<T>() { MyFunction = func };
    }

    public MyClass()
    {
    }

    public Func<T, T> MyFunction
    {
        get;
        set;
    }
}

Ваше определение TestFunction в вашем вопросе должно работать точно так, как вы его закодировали.

public T TestFunction<T>(IMyInterface myInterface, T value)
{
    return myInterface.MyFunction(value);
}

А также звонок на TestFunction:

TestFunction<string>(x => return x + " world", "hello");

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

...