我有以下协变界面:
public interface IHierarchical<out T> where T : IHierarchical<T> {
T Parent { get; }
IEnumerable<T> Children { get; }
}
然后我有以下接口派生自上面的接口:
public interface ISiteMapNode<T> : ISiteMapNode where T : ISiteMapNode<T> { }
public interface ISiteMapNode : IHierarchical<ISiteMapNode> {
string Name { get; set; }
}
最后,我有以下实现:
public class SiteMapNode : ISiteMapNode<SiteMapNode> {
public string Name { get; set; }
public ISiteMapNode Parent { get; }
public IEnumerable<ISiteMapNode> Children { get; }
}
现在我有一个方法,它接受ISiteMapNode类型的参数并尝试设置Parent属性。显然这不会起作用,因为Parent属性是只读的。我不得不删除set以使IHierachical接口协变。我有什么方法可以做到这一点吗?
答案 0 :(得分:2)
不,你不能。
您可以在类型参数之前考虑out
关键字,因为声明的接口只返回指定类型的(或输出)值。这类似于in
关键字,表示声明的接口只接受指定类型的值为 input 。
out
=值只出去了
in
=值只能进入
协变类型参数:
interface IHierarchical<out T>
{
T Parent
{
get; // OK -- it's going out
set; // ERROR
}
}
逆变型参数:
interface IHierarchical<in T>
{
T Parent
{
get; // ERROR
set; // OK -- it's going in
}
}
不变类型参数:(正常)
interface IHierarchical<T>
{
T Parent
{
get; // OK
set; // OK
}
}
一种替代方法是将接口拆分为协变和逆变子接口。像这样:
interface IHierarchical<T> : IHierarchicalIn<T>, IHierarchicalOut<T>
{
}
interface IHierarchicalIn<in T>
{
T Parent { set; }
}
interface IHierarchicalOut<out T>
{
T Parent { get; }
}
class Node : IHierarchical<Node>
{
public Node Parent
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
但是,我并没有真正看到它的用途。