Подтвердить что ты не робот

Метод расширения, который расширяет T - плохая практика?

Я читал, что обычно сложно использовать System.Object, с которым я согласен.

Мне любопытно, однако, если следующее будет считаться полезным методом расширения, или это все еще плохая практика?

Он похож на расширение System.Object, но не точно,

    public static R InvokeFunc<T, R>(this T input, Func<T, R> func)
    {
        return func.Invoke(input);
    }

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

Мысли?

4b9b3361

Ответ 1

Ну, здесь есть два момента:

1) Хорошо ли создавать метод расширения с помощью this T, поэтому он будет применяться ко всем типам?

2) Полезен ли конкретный метод расширения?

Для первого вопроса ответ иногда зависит от контекста. У вас может быть метод расширения применим ко всем классам, так же как linq гарантирует, что вы выберете подходящее пространство имен. Я бы подумал, что создание такого типа метода расширения в пространстве имен System является плохим, но если бы оно было более целенаправленным, возможно, это было бы полезно.

Для второго, так как вызов немедленно, выбор синтаксиса выглядит следующим образом

    int res = other.InvokeFunc<Other, int>(Callback);

    var res2 = (new Func<Other, int>(Callback))(other);

    var res3 = Callback(other);

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

Ответ 2

Все это значит, что он дает вам возможность ссылаться на метод как параметр, который на самом деле означает делегаты уже позволяют вам С#.

Я не вижу его более полезным (в случае IoC), чем делегат типа Func<T,R> в вашем случае. Это просто еще один способ вызвать его.

UPDATE

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

public static Func<R> InvokeFunc<T, R>(this T input, Func<T, R> func)
{
    return () => func(input);
}