加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 不能隐式转换类型 – 泛型

发布时间:2020-12-15 23:40:42 所属栏目:百科 来源:网络整理
导读:我有一个通用类Zone T其中T:Media.Medium.在这个类中,我有一个方法public void AddNode(Node node),其中我有一个语句node.ParentZone = this,它引发了这个编译错误: Cannot implicitly convert type ‘Zone T ’ to ‘Zone Media.Medium ’ 但我无法理解为
我有一个通用类Zone< T>其中T:Media.Medium.在这个类中,我有一个方法public void AddNode(Node node),其中我有一个语句node.ParentZone = this,它引发了这个编译错误:

Cannot implicitly convert type ‘Zone< T >’ to
‘Zone< Media.Medium >’

但我无法理解为什么公共抽象类Node具有公共区域< Media.Medium> ParentZone字段和类Zone< T>其中T:Media.Medium受T:Media.Medium的约束,所以在任何情况下T都是Media.Medium.

这是隔离的代码:(区域< T>以及Node的相关部分)

public class Zone<T> where T: Media.Medium
{
    public readonly Type MediaType = typeof(T);
    public readonly Guid ID = new Guid();

    private readonly List<Node> _nodes = new List<Node>();

    public void AddNode(Node node)
    {
        foreach (var port in node.GetPorts())
        {
            port.Medium = Activator.CreateInstance<T>();
        }

// Compile error in the line below

node.ParentZone = this;

// Cannot implicitly convert type ‘Zone< T >’ to
‘Zone< Media.Medium >’

_nodes.Add(node);
    }



    public List<Node> GetNodes() => new List<Node>(_nodes);

    public void RemoveNode(Node node) => _nodes.Remove(node);


}





public abstract class Node
{       
    public Zone<Media.Medium> ParentZone;

    ...
}

更新#1:

我这个代码的目标是:我想将Node对象添加到Zone对象,Zone对象有一个Node对象列表.每当我向区域添加节点时,我想将该Zone对象设置为Node对象的父节点.

我愿意为实现这一目标而进行任何重构.如果有更好的那个,就不应该这样.

解决方法

您应该清楚,泛型约束不提供泛型类型之间的可分配性.或者表达方式不同:如果泛型类从另一个类继承并共享相同的类型参数,则可以将其分配给另一个类.例如:

class Zone<T> where T : Medium { }

class ChildZone<T>: Zone<T>  where T : Medium { }

class Medium { }

class ChildMedium : Medium { }

什么有效:

Zone<Medium> mediumZone = new ChildZone<Medium>();
Zone<ChildMedium> childMediumZone = new ChildZone<ChildMedium>();

什么行不通:

Zone<Medium> mediumZone = new Zone<ChildMedium>();
ChildZone<Medium> childMediumZone = new ChildZone<ChildMedium>();

为什么?因为继承在泛型类中起作用,而不是泛型参数.考虑一下:

class Zone<T> {
   T Value { get; set; }
}

区域< Medium>的实例可以在Value属性中读取和写入Medium类型的项目.这意味着它可以读取和写入Medium和ChildMedium.相反,Zone< ChildMedium>只能读写ChildMedium.这里的问题是setter,因为不可能将Medium分配给Zone< ChildMedium> .Value,而不是分配给Zone< Medium> .Value.这使得类型不兼容.

如果您的Zone类是一个接口,并且您确保它只返回T类型的值,但您无法设置该类型的值,则可以使用covariance:

interface IZone<out T> {
    T Value { get; }
}

如果您需要读取和写入值,您唯一的选择是使Node也是通用的并传递通用约束:

namespace Core.Nodes
{
    public abstract class Node<T> where T : Media.Medium
    {       
        public Zone<T> ParentZone;

        //...
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读