c#存储不同的子类并同时调用它们



实际上所有这些类都是在第3个库中定义的,所以我不能更改它们。

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

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

class ParentClass
{
....
};
class ChildA : ParentClass
{
public string name;
};
class ChildB : ParentClass
{
public string name;
};

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

但是我不能得到name因为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?
}

我该如何处理这个?

简写为"no"。如果您可以访问类型,可以做一些事情—例如,您可以实现一个公共接口(interface IHazName { public string Name {get;} })—但是您不能在这里这样做,因为您不控制类型。

一种偷懒的方法可能是滥用dynamic:

dynamic hack = pc;
hack.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("Unexpected object type", nameof(obj)),
};
}
...
foreach (ParentClass pc in dict.Values) 
{
Console.WriteLine(pc.GetName());
}

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

这样做的一种方法是对类型使用反射来确定它是否有"名称";属性(或字段,如您所示):

public static string GetName(ParentClass parent)
{
return parent.GetType().GetProperty("name")?.GetValue(parent, null).ToString()
?? parent.GetType().GetField("name")?.GetValue(parent).ToString();
}

使用例子:

static void Main(string[] args)
{
ParentClass parent = new ParentClass();
ChildA child = new ChildA { name = "ChildName" };
Console.WriteLine($"Parent name: {GetName(parent)}");
Console.WriteLine($"Child name: {GetName(child)}");
Console.Write("nnDone. Press any key to exit...");
Console.ReadKey();
}

输出
Parent name:
Child name: ChildName

Done. Press any key to exit...

最新更新