简体   繁体   English

在协变接口上设置属性

[英]Set Property on a Covariant Interface

I have the following covariant interface: 我有以下协变接口:

public interface IHierarchical<out T> where T : IHierarchical<T> {
    T Parent { get; }
    IEnumerable<T> Children { get; }
}

I then have the following interfaces which derive from the interface above: 然后,我有以下接口,它们是从上面的接口派生的:

public interface ISiteMapNode<T> : ISiteMapNode where T : ISiteMapNode<T> { }

public interface ISiteMapNode : IHierarchical<ISiteMapNode> {
    string Name { get; set; }
}

Finally I have the following implementation: 最后,我有以下实现:

public class SiteMapNode : ISiteMapNode<SiteMapNode> {
    public string Name { get; set; }
    public ISiteMapNode Parent { get; }
    public IEnumerable<ISiteMapNode> Children { get; }
}

Now I have a method which takes an argument of type ISiteMapNode and tries to set the Parent property. 现在,我有了一个采用ISiteMapNode类型的参数并尝试设置Parent属性的方法。 Obviously this won't work as the Parent property is readonly. 显然,这是不起作用的,因为Parent属性是只读的。 I had to remove set to make the IHierachical interface covariant. 我必须删除集合以使IHierachical接口协变。 Is there any way I can do this? 有什么办法可以做到吗?

No you cannot. 你不能。

You can think of the out keyword before a type argument as saying that the declared interface will only return (or output ) values of the specified type. 您可以在类型参数之前想到out关键字,这意味着声明的接口将仅返回(或输出 )指定类型的值。 This is analogous to the in keyword saying that the declared interface will only accept values of the specified type as input . 这类似于in关键字,即声明的接口将仅接受指定类型的值作为input

out = values are ONLY going out out =值仅会消失
in = values are ONLY going in in =值仅进入

Covariant type parameter: 协变类型参数:

interface IHierarchical<out T>
{
    T Parent
    {
        get; // OK -- it's going out
        set; // ERROR
    }
}

Contravariant type parameter: 变量类型参数:

interface IHierarchical<in T> 
{
    T Parent
    {
        get; // ERROR
        set; // OK -- it's going in
    }
}

Invariant type parameter: (normal) 不变类型参数:(正常)

interface IHierarchical<T> 
{
    T Parent
    {
        get; // OK
        set; // OK
    }
}

One alternative could be to split the interface into a covariant and a contravariant subinterface. 一种替代方法是将接口拆分为协变和逆变子接口。 Something like this: 像这样:

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(); }
    }
}

I don't really see a use for that though. 不过,我确实没有看到任何用处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM