C# 访问派生类中的字段

C# 访问派生类中的字段,c#,C#,我正在通过用户界面动态创建节点列表。在我的列表中,我可以根据下面的类结构,通过反射实例化这些对象,将任意数量的对象AAA、BBB等添加到列表中 public abstract class Node : IDisposable { protected int x; } public class AAA : Node { public int iA; } public class BBB : Node { public int iB; } 创建列表后,我希望访问派生对

我正在通过用户界面动态创建节点列表。在我的列表中,我可以根据下面的类结构,通过反射实例化这些对象,将任意数量的对象AAA、BBB等添加到列表中

public abstract class Node : IDisposable
{ 
    protected int x;
}
public class AAA : Node
{ 
    public int iA;
}
public class BBB : Node
{ 
    public int iB;
}
创建列表后,我希望访问派生对象中的扩展字段。我知道我必须向下转换才能访问扩展字段,但为了做到这一点,目前我必须执行显式转换

foreach (Node nn in MyList)                   //assume the first node in the list is AAA
{
    int m = ((namespace.AAA) nn).iA;          //this works
    int n = (AAA) nn).iA;                     //this works
}
我想知道是否可以使用字符串来创建实际的向下投射。也许这是不可能的。也许我错过了什么。我想做的不起作用的事情如下

foreach (Node nn in MyList)       //assume the first node in the list is AAA
{
    Type t2 = nn.GetType();       //{Name = AAA; FullName = namespace.AAA} (*debugger*)
    string str = t2.FullName;     //namespace.AAA

    int m = ((str) nn).iA;         //this DOESN'T work
}
当我在调试器中查看nn的值时,全名表示我要用于向下转换的类

我可以在cast语句中使用基于表示类的字符串和硬代码的switch语句来解决这个问题,但是因为我有100多个不同的节点,并且将来我将添加更多的节点,所以每次添加节点时我都必须修改switch语句。如果可能的话,这是我不愿意做的事情

提前感谢您的回复

感谢道格拉斯指出我可以使用FieldInfo获得iA的值。我只是想在这个话题上再做一点扩展。如果我想使用AAA类并通过组合扩展它,那么我也可以通过FieldInfo访问这些类中的字段

public class AAA : Node
{ 
    public int iA;
    public X[] XArray;   //where X is some other random class with pubic fields
    public Y[] YArray;   //where Y is some other abstract class
 }

你所做的似乎是你设计中某个错误想法的产物

类中没有iA和iB,为什么基节点没有在AAA或BBB的构造函数中设置名为iNodeImplementation的属性?那你就不必做这些花哨的演员了


我有一种感觉,你试图变得太可爱,却错过了一些基本的OOD原则。考虑如何重构类,使代码更简单。

不考虑是否应该完成这一优点,这里有一些示例代码演示如何使用反射:

Type aaaType = Type.GetType("namespace.AAA");
FieldInfo iAField = aaaType.GetField("iA", BindingFlags.Public | 
                                           BindingFlags.Instance);
int m = (int)iAField.GetValue(nn);

为什么不尝试在节点类中设置抽象属性,而在AAA和BBB中实现呢

public abstract class Node : IDisposable
{ 
    protected int x;
    public abstract int i;
}
public class AAA : Node
{ 
    public override int i;
}
public class BBB : Node
{ 
    public override int i;
}
然后像这样使用foreach:

foreach (Node nn in MyList)       
{
    int m = nn.i;         
}

对我来说,这是对象设计中的问题,而不是C语言中的问题

你有很多节点,你想把它们处理得很好,但是你想以独特的方式从它们那里获得专门的数据。在拥有可能无限量的唯一数据的情况下,这并不是很好

问题在于,您需要两个方面的最佳效果:独特的封装数据和对该数据的免费通用访问

我想说的是,您需要进行节点设计,仔细考虑节点的一般消费者应该可以使用什么样的操作/访问,并在抽象基类或提供访问的少量接口中提供这些操作/访问


否则,您可能会在代码中的某个地方看到大量的向下转换,或者使用反射来进行最佳猜测,或者使用标准接口来描述和获取所需的值。

这看起来是泛型的完美用法,但要说更多,需要更多地了解应用程序的使用情况。您是否还需要一个switch语句来了解您是在AAA类型上查找属性iA还是在BBB类型上查找属性iB?给定一个节点,在编译时无法确定它是AAA还是BBB,所以你不能用强类型的方式来做这件事。我对OOP有点陌生。我们有大约100个不同的节点。我创建了一个抽象节点类型,它包含我们节点的所有共同特征。然后我需要从基本节点派生100个节点,在这些派生节点中,根据它们的操作扩展它们的特征。如果我有一个汽车类,我会衍生出福特、丰田等。在福特类中,我会在每一辆福特车上添加共同的功能。从福特级,我将衍生出野马级,并添加野马独有的特点。如果我创建了一个汽车列表,我想知道野马的轮胎。这就是我在创建汽车列表时要做的。也许我错了。