C# 中的合取类型
本文关键字:取类型 | 更新日期: 2023-09-27 18:37:25
C# 中泛型类的一个优点是可以对类型进行约束,以便只接受满足多个约束的类型。例如:
public class Foo<T> where T : Bar, IBaz, IFoobar {
public Foo (T value) {
//initialize
}
}
这意味着T
只能与派生自三个描述类的类型统一。
使用方法时,也可以使方法泛型。但是,我想知道为什么不能在构造函数中指定这样的约束。例如:
public class Foo {
public Foo (Bar & IBaz & IFoobar value) {
//initialize (the "&" syntax is just an example)
}
}
可以使类泛型,但如果只有构造函数将使用value
并且类的其他方法不依赖于T
,这可能会相当麻烦。有些问题甚至可能很难用泛型类来解决,例如,需要编写一个比较器SomeComparer<T,Q> : IComparer<Foo<T>,Foo<Q>>
引入大量实际上根本不泛型的泛型类。
我不明白为什么没有实现这一点,因为类型系统可以轻松检查参数是否满足所有类型约束。
在 C# 语言规范中不定义合取类型的参数是什么?
该功能可能很有用,但尚未实现。C# 团队只有这么多时间,我想这从来没有成功过。有很多事情使这变得困难:假设您有Foo
类和Foo<T>
类,每个类都有非泛型和Foo<U>
构造函数。如果你打电话给new Foo<int>(1)
,这是Foo..ctor<U>
还是Foo<T>..ctor
?Foo<T>..ctor<U>
被new Foo<int><string>("")
引用了吗?如果不引入一些新语法,并且以任何方式混淆我可以看到它正在完成,就无法完成它,所以也许最好不允许在构造函数上使用泛型。
您可以通过在非泛型类上编写泛型方法来解决此问题,例如
void Main()
{
Foo foo = Foo.GetInstance(new BarBazAndFoobarImplementer());
}
public sealed class Foo {
private Foo(Bar value) {
this.Thing1 = value.BarProperty;
this.Thing2 = ((IBaz)value).IBazProperty;
this.Thing3 = ((IFoobar)value).IFoobarProperty;
}
public static Foo GetInstance<T>(T value) where T : Bar, IBaz, IFoobar {
return new Foo(value);
}
}
(这不会受到上述问题的困扰,因为您可以明确地调用Foo.GetInstance<U>(..)
和Foo<T>.GetInstance<U>(..)
)
可以完成这样操作的一种方法是使用私有构造函数和工厂方法:
public class Foo
{
public static Foo Create<T>(T value) where T : Bar, IBaz, IFoobar
{
return new Foo(value);
}
private Foo(Bar value)
{
// whatever
// feel free to cast to IBaz or IFoobar as needed
}
}
不能使用构造函数执行此操作,因为构造函数应该构造其类型的实例。你会用value
做什么?也许将其存储在字段中,但是字段的类型是什么?
更好的方法可能是 Bar
或从 Bar
派生的类实现这两个接口。