考虑这个虚构的例子......
public abstract class CollectionItem<TSelf> {
protected CollectionItem(ICollection<TSelf> siblings)
=> Siblings = siblings;
public ICollection<TSelf> Siblings { get; }
}
public class Foo : CollectionItem<Foo>{
public Foo()
: base(new FooCollection){}
}
public class FooCollection : ObservableCollection<Foo>{
}
有了上面的内容,Foo
现在有一个Siblings
财产。然而,这存在三个问题。
- 我必须重复多余的
Foo
在一般情况下
-
Siblings
它本身不是实际集合类型的类型,而是接口的类型。
- 我实际上必须传递一个实例
Siblings
收藏
解决#2和#3,我做了这个改变......
public class CollectionItem<TSelf, TSiblings>
where TSiblings : ICollection<TSelf>, new() {
protected CollectionItem()
=> Siblings = new TSiblings();
public TSiblings Siblings { get; }
}
但我还是要传入看似多余的Foo
作为第一个类型参数,像这样......
public class Foo : CollectionItem<Foo, FooCollection>{
}
在 Swift 中,你有一个隐式的Self
datatype 始终表示当前实例的类型,这意味着如果Self
用于基类中,它实际上是子类数据类型的替代。如果愿意的话,可以将其视为隐式泛型。
在 C# 中拥有它可以让我做这样的事情......
public class CollectionItem<TSiblings>
where TSiblings : ICollection<Self>, new() { // Note it uses 'Self' here
protected CollectionItem()
=> Siblings = new TSiblings();
public TSiblings Siblings { get; }
}
public class Foo : CollectionItem<FooCollection>{
}
public class Laa : CollectionItem<LaaCollection>{
}
在上面的例子中,Foo
, Self
指的是Foo
。对于以下实例Laa
, Self
指的是Laa
。无需传递多余的类型参数。
那么C#有类似的东西吗?