【问题标题】:Passing a generic object with type that is derived from the required type传递具有从所需类型派生的类型的泛型对象
【发布时间】:2020-09-21 13:10:31
【问题描述】:

是否可以将泛型对象作为参数传递给从预期类类型派生的类类型?

下面的代码导致编译器错误,cannot convert from ItemObject<Equipment> to ItemObject<Item>,我觉得这很奇怪,因为 Equipment 继承自 Item

using System.Collections.Generic;

public abstract class Item { }

public abstract class Equipment : Item { }

public class ItemObject<T> where T : Item { }

public class EquipmentManager
{
    ItemObject<Equipment> equipment = new ItemObject<Equipment>();

    public void Unequip()
    {
        Inventory.instance.AddItem(equipment);
    }
}

public class Inventory
{
    public static Inventory instance;
    List<ItemObject<Item>> items = new List<ItemObject<Item>>();

    public void AddItem(ItemObject<Item> _item)
    {
        items.Add(_item);
    }

}

【问题讨论】:

  • 您的 Equipment 类不应该从 ItemObject 继承吗?

标签: c# generics inheritance arguments


【解决方案1】:

这里的问题不在于Equipment 继承自Item。问题是您正在从泛型类创建特定类型。 ItemObject&lt;T&gt;-> ItemObject&lt;Equipment&gt;。没有将ItemObject&lt;Equipment&gt; 转换为ItemObject&lt;Item&gt; 的显式或隐式方法。

如果您有一个ItemObject&lt;Item&gt; 并尝试添加一个Equipment 来代替Item,那么隐式转换将起作用。在这种情况下,Equipment 在传递给ItemObject&lt;Item&gt; 的方法之前将被隐式转换为Item

【讨论】:

    【解决方案2】:

    您可以使用协方差来实现这一点,这将允许您使用更派生的类型。但是,这只能应用于接口,因此您需要执行以下操作:

    public abstract class Item { }
    
    public abstract class Equipment : Item { }
    
    public interface IItemObject<out T> where T : Item { }
    public class ItemObject<T> : IItemObject<T> where T : Item { }
    
    public class EquipmentManager {
        IItemObject<Equipment> equipment = new ItemObject<Equipment>();
    
        public void Unequip() {
            Inventory.instance.AddItem(equipment);
        }
    }
    
    public class Inventory {
        public static Inventory instance;
        List<IItemObject<Item>> items = new List<IItemObject<Item>>();
    
        public void AddItem(IItemObject<Item> _item) {
            items.Add(_item);
        }
    }
    

    更多阅读covariance and contravariance

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 2011-10-09
      • 2011-05-24
      • 2012-09-08
      • 2015-01-26
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多