Существует ли разумный подход к параметрам типа “по умолчанию” в C # Generics?

StackOverflow https://stackoverflow.com/questions/707780

Вопрос

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

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

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

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

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

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

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

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

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

Это было полезно?

Решение

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

Я бы выделил ваш основной универсальный класс в подкласс:

class BaseGeneric<T,U>

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

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

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

Другие советы

Одним из решений является создание подклассов.Другой, который я бы использовал вместо этого, - это фабричные методы (в сочетании с ключевым словом 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> и не тип, производный от него.

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

вы также можете создать перегрузку класса следующим образом

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

public class MyTemplate<T1> : MyTemplate<T1, string>{}

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top