在协变接口上设置属性

本文关键字:设置 属性 接口 | 更新日期: 2023-09-27 18:26:00

我有以下协变接口:

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属性是只读的,因此这将不起作用。我不得不删除集合,使IHierachical接口协变。有什么办法我能做到这一点吗?

在协变接口上设置属性

不可以。

您可以将类型参数之前的out关键字视为声明的接口将只返回指定类型的值(或输出)。这类似于in关键字,即声明的接口将只接受指定类型的值作为输入

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

不过,我真的看不出有什么用。