Есть ли разумный подход к параметрам типа «по умолчанию» в C # Generics? - PullRequest
75 голосов
/ 02 апреля 2009

В шаблонах C ++ можно указать, что определенный тип параметра является значением по умолчанию. То есть если явно не указано, он будет использовать тип T.

Можно ли это сделать или приблизить в C #?

Я ищу что-то вроде:

public class MyTemplate<T1, T2=string> {}

Так что экземпляр типа, который явно не указывает T2:

MyTemplate<int> t = new MyTemplate<int>();

Было бы по существу:

MyTemplate<int, string> t = new MyTemplate<int, string>();

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

Ответы [ 5 ]

67 голосов
/ 02 апреля 2009

Подклассификация - лучший вариант.

Я бы подкласс вашего основного общего класса:

class BaseGeneric<T,U>

с определенным классом

class MyGeneric<T> : BaseGeneric<T, string>

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

16 голосов
/ 15 декабря 2014

Одним из решений является создание подклассов. Вместо этого я бы использовал фабричные методы (в сочетании с ключевым словом var).

public class MyTemplate<T1,T2>
{
     public MyTemplate(..args..) { ... } // constructor
}

public static class MyTemplate{

     public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
     {
         return new MyTemplate<T1, T2>(... params ...);
     }

     public static MyTemplate<T1, string> Create<T1>(...args...)
     {
         return new MyTemplate<T1, string>(... params ...);
     }
}

var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();

В приведенном выше примере val2 имеет тип MyTemplate<int,string> , а не тип, производный от него.

Тип class MyStringTemplate<T>:MyTemplate<T,string> отличается от типа MyTemplate<T,string>. Это может создать некоторые проблемы в определенных сценариях. Например, вы не можете привести экземпляр MyTemplate<T,string> к MyStringTemplate<T>.

10 голосов
/ 02 декабря 2015

вы также можете создать класс Overload, например, так:

public class MyTemplate<T1, T2> {
    public T1 Prop1 { get; set; }
    public T2 Prop2 { get; set; }
}

public class MyTemplate<T1> : MyTemplate<T1, string>{}
8 голосов
/ 02 апреля 2009

C # не поддерживает такую ​​функцию.

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

2 голосов
/ 02 апреля 2009

К сожалению, C # не поддерживает то, что вы пытаетесь сделать. Это было бы трудно реализовать, учитывая, что тип по умолчанию для параметра должен был бы соответствовать общим ограничениям и, скорее всего, вызывал бы головную боль, когда CLR пытался обеспечить безопасность типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...