[*] Интерфейсы позволяют классу формально указать свой публичный контракт, методы и свойства, которые они подвергают миру. /> Методы расширения могут быть определены on интерфейс, предоставляя любую функциональность, которая может быть реализована через интерфейс для всех реализаторов автоматически .
И лучше всего, из -за «синтаксиса экземпляра», «Синтаксис экземпляра». /> < /ul>
Таким образом, вы получаете преимущества инкапсуляции функций «не члена, не подругана» с удобством участников. Кажется мне лучшим из обоих миров; Сама библиотека .NET дает яркий пример в LINQ. Однако везде я смотрю, я вижу, как люди предупреждают о чрезмерном использовании метода расширения; Даже сама страница MSDN гласит: < /p>
В целом, мы рекомендуем вам реализовать методы расширения и только тогда, когда вам нужно. Функции утилиты списка (
Код: Выделить всё
Sort
edit3: переопределяемые методы расширения < /h3>
Единственная реальная проблема, идентифицированная до сих пор с этим подходом, заключается в том, что вы не можете специализировать методы расширения, если вам нужно. Я думал об этой проблеме, и я думаю, что придумал решение.
Предположим, у меня есть интерфейс myInterface , который я хочу расширить -
Я определяю свои методы расширения в myextension . Myextension Методы определяются в соответствии с этой шаблоном:
Код: Выделить всё
public static int MyMethod(this MyInterface obj, int arg, bool attemptCast=true)
{
if (attemptCast && obj is MyExtensionOverrider)
{
return ((MyExtensionOverrider)obj).MyMethod(arg);
}
// regular implementation here
}
public interface MyExtensionOverrider
{
int MyMethod(int arg);
string MyOtherMethod();
}
< /code>
Теперь любой класс может реализовать интерфейс и получить функцию расширения по умолчанию: < /p>
public class MyClass : MyInterface { ... }
< /code>
Любой, кто хочет переопределить его с помощью конкретных реализаций, может дополнительно реализовать интерфейс переопределения: < /p>
public class MySpecializedClass : MyInterface, MyExtensionOverrider
{
public int MyMethod(int arg)
{
//specialized implementation for one method
}
public string MyOtherMethod()
{ // fallback to default for others
MyExtension.MyOtherMethod(this, attemptCast: false);
}
}
< /code>
И мы идем: методы расширения, предоставленные на интерфейсе, с опцией полной расширяемости при необходимости. Также общее, сам интерфейс не должен знать о расширении /переопределении, и множественные пары расширения /переопределения могут быть реализованы, не мешая друг другу. /> Это немного уродливое - реализация интерфейса переопределения включает в себя шаблон для каждой функции, которую вы Не Хотите специализироваться. Лучше всего получить, пока не появится языковая поддержка для интерфейсных функций. Мысли?
Подробнее здесь: https://stackoverflow.com/questions/303 ... eusability