Метод расширения, который расширяет T - плохая практика?
Я читал, что обычно сложно использовать System.Object, с которым я согласен.
Мне любопытно, однако, если следующее будет считаться полезным методом расширения, или это все еще плохая практика?
Он похож на расширение System.Object, но не точно,
public static R InvokeFunc<T, R>(this T input, Func<T, R> func)
{
return func.Invoke(input);
}
Это по существу позволяет любому объекту вызывать любую функцию, которая принимает этот объект в качестве параметра и возвращает R, принадлежит ли эта функция к объекту или нет. Я думаю, что это могло бы облегчить интересную "инверсию контроля", но не уверен в этом.
Мысли?
Ответы
Ответ 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);
}