gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:06:41 25 4
gpt4 key购买 nike

我有一个通用类 Zone<T> where T: Media.Medium .在这个类中我有一个方法 public void AddNode(Node node)其中我有一个声明 node.ParentZone = this这引发了这个编译器错误:

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

但我不明白为什么 public abstract class Nodepublic Zone<Media.Medium> ParentZone字段和类 Zone<T> where T: Media.Mediumwhere T: Media.Medium 约束, 所以 T 是 Media.Medium在任何情况下。

这是独立的代码:(完整的 Zone<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 objects 有一个列表 Node对象。每当我添加 NodeZone , 我想设置 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; }
}

Zone<Medium> 的实例可以读取类型为Medium的项目在其 Value属性(property)。这意味着它可以读写,MediumChildMedium .相比之下,Zone<ChildMedium>只能读写ChildMedium .这里的问题是 setter ,因为不可能分配 MediumZone<ChildMedium>.Value , 但不是 Zone<Medium>.Value .这使得类型不兼容。

如果您的 Zone class 将是一个接口(interface),你确保它只返回一个 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;

//...
}
}

关于c# - 不能隐式转换类型 - 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46092521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com