Вот интересная проблема, с которой я только что столкнулся. Можно делать то, что я хочу, используя методы расширения, но не представляется возможным сделать с членами самого класса.
С помощью расширенных методов можно написать метод с сигнатурой, который выглядит следующим образом:
public static void DoStuff<T>(this T arg1, T arg2)
это означает, что оба аргумента относятся к тому типу, к которому вы обращаетесь. Это становится более полезным при использовании с делегатами.
public static void DoStuff<T>(this T arg1, Action<T> arg2)
Однако я не могу заставить это работать с участниками. Нет такого ограничения, как это:
public void DoStuff<T>(T arg1) where T : typeof(this)
если это сработало, вы могли бы определить метод в своем базовом классе следующим образом (я использовал потоки, поскольку они являются встроенной иерархией в .NET):
class Stream
{
public void DoStuff<T>(T stream) where T : this
{
}
}
и тогда на подклассе было бы невозможно назвать его так:
ByteStream bs = new ByteStream()
bs.DoStuff(new Stream()) // Error! DoStuff() should be inferred as DoStuff<ByteStream>()
Есть ли способ сделать это? Я считаю, что автоматически выводить типы из аргументов, а методы расширения являются синтаксическим сахаром. И это, вероятно, почему это работает; потому что методы расширения заменяются статическими вызовами, которые затем позволяют выводить тип.
Я спрашиваю, потому что я пытаюсь переместить метод расширения в общий базовый класс и не могу заставить его скомпилироваться без добавления информации о типе.
Чтобы уточнить. Это не просто добавление where T : MyType
, потому что если я создам тип с именем MySubType
, который наследуется от MyType
, я смогу вызвать DoStuff
в экземпляре MySubType
и передать MyType
в качестве параметра. Это также означает, что в случае, когда требуется Action<T>
, я не смогу вызвать методы MySubType
без предварительного приведения.