98

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

这可以在 C# 中完成或近似吗?

我正在寻找类似的东西:

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

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

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

基本上是:

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

最终,我正在研究一个案例,其中有一个相当广泛使用的模板,但我正在考虑使用额外的类型参数进行扩展。我想我可以子类化,但我很好奇这方面是否还有其他选择。

4

6 回答 6

82

子类化是最好的选择。

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

class BaseGeneric<T,U>

有一个特定的班级

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

这使得将您的逻辑保存在一个地方(基类)很容易,而且也很容易提供两种使用选项。根据班级的不同,实现这一点可能需要很少的额外工作。

于 2009-04-01T23:53:38.797 回答
22

一种解决方案是子类化。我将使用的另一种方法是工厂方法(结合 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>转换 to的实例MyStringTemplate<T>

于 2014-12-15T16:34:14.260 回答
15

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

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

public class MyTemplate<T1> : MyTemplate<T1, string>{}
于 2015-12-02T02:23:07.537 回答
10

C# 不支持这样的功能。

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

于 2009-04-01T23:54:56.967 回答
3

不幸的是,C# 不支持您正在尝试做的事情。考虑到参数的默认类型必须遵守泛型约束,并且当 CLR 试图确保类型安全时很可能会让人头疼,这将是一个难以实现的功能。

于 2009-04-01T23:57:09.990 回答
1

如果要将类型重载到接口,可以这样做: 示例:

public interface ISRD<TItem, TId>
{
    Task SaveAsync(TItem item);
    Task<TItem> GetAsync(TId id);
    Task DeleteAsync(TItem item);
}

public interface ISRD<TItem>: ISRD<TItem, Guid> { }
于 2022-01-18T00:35:37.633 回答