【问题标题】:C# store different child classes and call them at same timeC# 存储不同的子类并同时调用它们
【发布时间】:2023-01-05 22:50:40
【问题描述】:

实际上所有这些类都在第三个库中定义,所以我无法更改它们。

=====================

我正在学习 C#,但遇到了一个问题。 假设我有一个父类和两个子类:

class ParentClass
{
    ....
};

class ChildA : ParentClass
{
    public string name;
};

class ChildB : ParentClass
{
    public string name;
};

ChildA 和 ChildB 类都具有属性 name,但 ParentClass 没有。 现在我需要将 ChildA 和 ChildB 存储在字典中,所以我写 Dictionary<string, ParentClass>

但我无法获取名称,因为 ParentClass 没有此属性:

foreach (ParentClass pc in dict.Values) 
{
    // it works, but too verbose as I may have ChildC, ChildD...
    if (pc is ChildA ca) 
    {
        ca.name
    }
    if (pc is ChildB cb) 
    {
        cb.name
    }

    // how can I get the name property at same time?
}

我该如何处理?

【问题讨论】:

  • 您是否尝试过在父组件中添加 name 属性并将其从子组件中删除?
  • 当父类不知道该属性并且您无法更改它时,除了向下转换为适当的 child.class 并在那里调用成员之外别无他法。

标签: c# inheritance


【解决方案1】:

简短的版本是“否”。有些事你可以如果您有权访问这些类型,请执行此操作 - 例如,您可以实现一个通用接口 (interface IHazName { public string Name {get;} }) - 但您不能在此处执行此操作,因为您无法控制这些类型。

一个懒惰的方法可能是滥用dynamic

dynamic hack = pc;
pc.name = "yolo";

但是……请不要!您的 is 方法(或者可能是 switch 表达式)已尽您所能。请注意,如果您需要在很多地方与该成员交谈,您可以将该共享逻辑移动到扩展方法:

static class SomeUtilsType {
    public static string GetName(this ParentClass obj) => obj switch {
        ChildA ca => ca.name,
        ChildB cb => cb.name,
        _ => throw new ArgumentException(),
    };
}
...
foreach (ParentClass pc in dict.Values) 
{
    Console.WriteLine(pc.GetName());
}

(或类似的设置方法)——那么至少你不需要重复自己。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 2020-04-15
    • 2021-08-03
    相关资源
    最近更新 更多