在协变接口上设置属性

时间:2014-10-09 10:34:47

标签: c# covariance

我有以下协变界面:

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接口协变。我有什么方法可以做到这一点吗?

1 个答案:

答案 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(); }
    }
}
但是,我并没有真正看到它的用途。