C#泛型中是否有合理的"默认"类型参数方法?

el2*_*ot2 80 c# generics parameters types default

在C++模板中,可以指定某个类型参数是默认值.即除非明确指定,否则它将使用类型T.

可以用C#完成或近似吗?

我正在寻找类似的东西:

public class MyTemplate<T1, T2=string> {}
Run Code Online (Sandbox Code Playgroud)

这样一个没有明确指定的类型的实例T2:

MyTemplate<int> t = new MyTemplate<int>();
Run Code Online (Sandbox Code Playgroud)

基本上是:

MyTemplate<int, string> t = new MyTemplate<int, string>();
Run Code Online (Sandbox Code Playgroud)

最后,我正在研究一个案例,其中有一个相当广泛使用的模板,但我正在考虑使用其他类型参数进行扩展.我想,我可以继承,但我很好奇是否还有其他选择.

Ree*_*sey 72

子类化是最佳选择.

我会继承你的主要泛型类:

class BaseGeneric<T,U>

与特定的类

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

这使您可以轻松地将逻辑保存在一个位置(基类),但也很容易提供两种使用选项.根据班级的不同,实现这一目标可能需要额外的工作.

  • 例如,Predicate <T>只是Func <T,bool>,但是因为它用于不同的目的而重命名. (4认同)
  • @ee:是的,泛型是参数计数的"可重载". (2认同)

Tha*_*dis 19

一种解决方案是子类化.我将使用的另一个是工厂方法(与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>();
Run Code Online (Sandbox Code Playgroud)

在上面的例子中val2是类型MyTemplate<int,string> 而不是从中派生的类型.

类型class MyStringTemplate<T>:MyTemplate<T,string>与类型不同MyTemplate<T,string>.这可能会在某些情况下造成一些问题.例如,您可以不投的实例MyTemplate<T,string>MyStringTemplate<T>.

  • 这是最有用的方法.很好的解决方案 (3认同)

Moe*_*oes 11

你也可以像这样创建一个Overload类

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

public class MyTemplate<T1> : MyTemplate<T1, string>{}
Run Code Online (Sandbox Code Playgroud)

  • 接受的答案是创建一个具有不同名称的类,我的解决方案是重载同一个类 (7认同)
  • 即使真实的类型不同,这是明确和正确的,如果你保持相同的名称,编码也会更容易.对于每个人来说,"过载"这种方式可以使用并不明显.@DannyChen是对的 - 从技术角度来看结果是一样的,但这个answear更接近实现OP所要求的. (7认同)
  • 不幸的是,这个解决方案仍然不如真正的“默认”通用参数,因为 `MyTemplate&lt;T1, string&gt;` 不能分配给 `MyTemplate&lt;T1&gt;`,这可能是理想的 (3认同)
  • 不,两者都在创建一个新类。名称在这里无关紧要。MyTemplate &lt;T1&gt;和MyTemplate &lt;T1,T2&gt;是不同的类,AnotherTemplate &lt;T1&gt;都不是。 (2认同)

Meh*_*ari 8

C#不支持这样的功能.

正如你所说,你可以将它子类化(如果它没有被密封,并复制所有构造函数声明),但这是完全不同的事情.