【问题标题】:Storing derived classes in a base class Dictionary将派生类存储在基类 Dictionary 中
【发布时间】:2023-03-28 16:04:01
【问题描述】:

我正在尝试创建一个场景或状态管理器,它为每个状态存储一个字典,作为加载或更改程序状态(例如,主菜单状态和游戏状态)的一种方式。我有一堆基类 State 的派生类,它们的变量未包含在基 State 类中。我可以安全地将它们存储在这本词典中吗?我会丢失任何数据吗?如果这不起作用,有什么替代方法可以实现我的目标?

【问题讨论】:

    标签: c# dictionary base derived


    【解决方案1】:

    这似乎是您可以轻松测试自己的东西。但只是为了好玩,假设你有一个像这样的基类:

    public class Base
    {
        public string Name
        {
            get;
            set;
        }
    
        public override string ToString()
        {
            return Name;
        }
    }
    

    还有一个派生类,例如:

    public class Derived : Base
    {
        public string Description
        {
            get;
            set;
        }
    
        public override string ToString()
        {
            return base.ToString() + " - " + Description;
        }
    }
    

    然后你可以像这样创建一个设置:

    Base baseObject = new Base{ Name = "Base"};
    Derived derivedObject = new Derived { Name = "Derived", Description = "Description" };
    
    Dictionary<int, Base> dictionary = new Dictionary<int, Base>();
    dictionary.Add(1, baseObject);
    dictionary.Add(2, derivedObject);
    

    现在您可以运行一个小测试来查看是否有任何信息丢失:

    foreach (Base value in dictionary.Values)
    {
        Console.WriteLine(value.ToString());
    }
    

    如您所见,不仅调用了正确的覆盖ToString(),而且它还具有Description 属性的正确值。所以不,你不会“失去”任何东西。但是只要是base类型,就只能直接访问base属性。

    顺便说一句。您还可以检查一个值是否真的是is 某个派生类型:

    foreach (Base value in dictionary.Values)
    {
        if (value is Derived)
        {
            Console.WriteLine("{0} is Derived", value.Name);
            // trying to access value.Description at this point
            // would cause a compiler error "Cannot resolve symbol".
        }
        else
        {
            Console.WriteLine("{0} is not Derived", value.Name);
        }
    }
    

    使用as 并检查空值,您可以“安全地”(即,例如,没有由直接转换引起的异常)获取“完整”派生类型中的值,您可以在其中再次访问所有附加属性:

    foreach (Base value in dictionary.Values)
    {
        Derived derived = value as Derived;
        if (derived != null)
        {
            Console.WriteLine("{0} is Derived and has Description: {1}",
                               derived.Name, derived.Description);
            // now that derived actually is of type Derived,
            // accessing derived.Description is perfectly fine.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-21
      • 2012-02-05
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2019-05-13
      • 1970-01-01
      相关资源
      最近更新 更多