1

我目前正在设计一个 winforms 应用程序,该应用程序需要能够将各种类中各种属性的值输出到串行/udp 端口​​。

我想知道是否有一种简单的方法可以在运行时迭代此项目中的所有类实例,然后向用户显示一个选择的一堆(可能是通过使用属性?)及其相应的字符串值,以便他们可以输出任何这些值的组合。

因此,对于(简化的)示例,假设我有两个类:

public class ClassA
{
  public double Price{get;set;}
  public int Units{get;set}
  //other properties that I don't want visible to the user
}

public class ClassB
{
  public string Name{get;set;}
  public string Description{get;set;}
  //other properties not visible to the user
}

我将在运行时实例化这些类的许多实例(它们可能不一定相互链接/引用/相关)。

例如

public ClassA Cars = new ClassA();
public ClassB Models = new ClassB();
public ClassA PCs = new ClassA();
//set properties of these instances
//etc.. more of these

我想收集所有这些实例并向用户显示相应的字段:

Cars.Price = "1000";
Cars.Units = "3";
Models.Name = "BMW";
Models.Description = "Luxury Car";
PCs.Price = "3000";
PCs.Units = "20";

请注意,这些值将在运行时发生变化,并且在发送数据时需要更新。我希望有人可以在这里为我指明正确的方向。

编辑

看起来这可能不可行。

有没有办法可以存储对象列表,这些对象指向我的属性/字段,以便我可以检索它的值?当然假设这些类实例只会创建一次,我可以在我的输出类中注册类属性/字段。那么输出类可以遍历这个列表,取回它所指向的对象的值,然后把需要的数据发送出去呢?

例如

class OutputData
{
  Dictionary<string,object> OutputDataList = new Dictionary<string,object>();

  public void RegisterData(string displayName, ref object dataField)
  {
    OutputDataList.Add(displayName,dataField);
  }

  //iterate over OutputDataList and get the value of the property/field it points to
}
4

2 回答 2

2

如果所有这些对象在应用程序的生命周期中都存在,并且您只需要跟踪所有这些对象,则可以在每个类的构造函数中执行此操作,例如:

public class Tracker
{
  public static List<object> AllObjects = new List<object>();
}

public class ClassA
{
   public ClassA()
   {
      Tracker.AllObjects.Add(this);
   }
   ...
}

这样,您只需要修改要跟踪的类,实例就会在整个列表中得到跟踪。对于要跟踪哪些字段的问题,您可以使用反射,也可以在所有对象中存储更有趣的Func<List<string>>内容,也许 a 返回所有感兴趣的值。

然后添加行将是:

      Tracker.AllObjects.Add(() => 
          { 
            yield return "Name:" + this.Name; 
            yield return "Description:" + this.Description;
          });

然后你可以这样做:

var ouputLines = Tracker.AllObjects.SelectMany(o => o());
于 2012-05-25T05:02:51.883 回答
1

好吧,这看起来像是一些领域

public ClassA Cars = new ClassA();
public ClassB Models = new ClassB();
public ClassA PCs = new ClassA();

所以让我们明确一点:

public class Something {
    public ClassA Cars = new ClassA();
    public ClassB Models = new ClassB();
    public ClassA PCs = new ClassA();
}

因此,假设这些是某物中的字段,快速通过反射将找到它们。到现在为止还挺好。

您需要了解的是,该字段的名称(例如“Cars”)与变量的实例无关 - 它与包含该字段的类的实例相关联,在本例中为 some Something

要理解为什么,想象一下这段代码:

var a = new Something();
var b = new Something();
b.PCs = a.Cars;

现在我们有一个 ClassA 类型的变量,它存储在 a.Carsb.PCs 中。你会使用哪个标签?

你需要有一本关于这些东西的字典,或者以其他方式限制它们的名称。这样的事情会做:

public Dictionary<String, Object> myStuff = new Dictionary<String, Object> { { "Cars", new ClassA() }, { "Models", new ClassB() }, { "PCs", new ClassA() } };

// then, to get the field names and values

var someObject = myStuff["PCs"];
foreach (var fi in someObject.GetType().GetFields()) {
    var fieldName = fi.Name;
    var fieldValue = fi.GetValue(someObject);
    // Do something here
}
于 2012-05-25T04:55:34.400 回答