C#泛型中的“默认”类型参数是否有合理的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/707780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a reasonable approach to "default" type parameters in C# Generics?
提问by el2iot2
In C++ templates, one can specify that a certain type parameter is a default. I.e. unless explicitly specified, it will use type T.
在 C++ 模板中,可以指定某个类型参数是默认值。即除非明确指定,否则它将使用类型 T。
Can this be done or approximated in C#?
这可以在 C# 中完成或近似吗?
I'm looking for something like:
我正在寻找类似的东西:
public class MyTemplate<T1, T2=string> {}
So that an instance of the type that doesn't explicitly specify T2
:
因此,未明确指定的类型的实例T2
:
MyTemplate<int> t = new MyTemplate<int>();
Would be essentially:
基本上是:
MyTemplate<int, string> t = new MyTemplate<int, string>();
Ultimately I am looking at a case wherein there is a template that is fairly widely used, but I am considering expanding with an additional type parameter. I could subclass, I guess, but I was curious if there were other options in this vein.
最终,我正在研究一个案例,其中有一个使用相当广泛的模板,但我正在考虑使用额外的类型参数进行扩展。我想我可以子类化,但我很好奇在这方面是否还有其他选择。
采纳答案by Reed Copsey
Subclassing is the best option.
子类化是最好的选择。
I would subclass your main generic class:
我会将您的主要泛型类子类化:
class BaseGeneric<T,U>
class BaseGeneric<T,U>
with a specific class
有一个特定的类
class MyGeneric<T> : BaseGeneric<T, string>
class MyGeneric<T> : BaseGeneric<T, string>
This makes it easy to keep your logic in one place (the base class), but also easy to provide both usage options. Depending on the class, there is probably very little extra work needed to make this happen.
这使得将您的逻辑放在一个地方(基类)很容易,而且也很容易提供两种使用选项。根据课程的不同,实现这一目标可能只需要很少的额外工作。
回答by Mehrdad Afshari
C# does not support such a feature.
C# 不支持这样的功能。
As you said, you can subclass it (if it's not sealed, and duplicate all constructor declarations) but it's a completely different thing.
正如您所说,您可以将其子类化(如果它没有密封,并复制所有构造函数声明),但这是完全不同的事情。
回答by Andrew Hare
Unfortunately C# does not support what you are trying to do. It would be a difficult feature to implement given that the default type for a parameter would have to adhere to the generic constraints and would most likely create headaches when the CLR tried to ensure type-safety.
不幸的是,C# 不支持您尝试执行的操作。考虑到参数的默认类型必须遵守泛型约束,并且当 CLR 试图确保类型安全时很可能会造成麻烦,这将是一个难以实现的功能。
回答by Thanasis Ioannidis
One solution is subclassing. Another one I would use instead, is factory methods (combined with var keyword).
一种解决方案是子类化。我将使用的另一种方法是工厂方法(与 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>();
In the above example val2
is of type MyTemplate<int,string>
and nota type derived from it.
在上面的例子中val2
是类型MyTemplate<int,string>
而不是从它派生的类型。
A type class MyStringTemplate<T>:MyTemplate<T,string>
is not the same type as MyTemplate<T,string>
.
This could pose some problems in certain scenarios.
For instance you can't cast an instance of MyTemplate<T,string>
to MyStringTemplate<T>
.
A型class MyStringTemplate<T>:MyTemplate<T,string>
是不相同的类型MyTemplate<T,string>
。在某些情况下,这可能会带来一些问题。例如,您不能将实例转换为MyTemplate<T,string>
to MyStringTemplate<T>
。
回答by Nerdroid
you can also create a class Overload like so
你也可以像这样创建一个类 Overload
public class MyTemplate<T1, T2> {
public T1 Prop1 { get; set; }
public T2 Prop2 { get; set; }
}
public class MyTemplate<T1> : MyTemplate<T1, string>{}