一种在整个项目中封装类属性的通用/简单方法
本文关键字:属性 封装类 方法 简单 项目 一种 | 更新日期: 2023-09-27 18:35:17
我目前正在设计一个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
}
如果所有这些对象在应用程序的生命周期内都存在,并且您只需要跟踪所有这些对象,则可以在每个类的构造函数中执行此操作,如下所示:
public class Tracker
{
public static List<object> AllObjects = new List<object>();
}
public class ClassA
{
public ClassA()
{
Tracker.AllObjects.Add(this);
}
...
}
这样,您只需修改要跟踪的类,实例将在整个列表中进行跟踪。 对于要跟踪哪些字段的问题,您可以使用反射,也可以在所有对象中存储更有趣的内容,也许是一个返回所有感兴趣值的Func<List<string>>
。
然后,添加行将为:
Tracker.AllObjects.Add(() =>
{
yield return "Name:" + this.Name;
yield return "Description:" + this.Description;
});
然后,您可以执行以下操作:
var ouputLines = Tracker.AllObjects.SelectMany(o => o());
这看起来像是某些东西的字段:
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")与变量的实例无关 - 它与包含该字段的类的实例相关联,在本例中为某些Something
。
要理解原因,请想象以下代码:
var a = new Something();
var b = new Something();
b.PCs = a.Cars;
现在我们有一个类型为 ClassA 的变量,它存储在 a.Cars 和 b.PC 中。 你会使用哪个标签?
你需要有一本这些东西的字典,或者限制它们的名字。 像这样的事情就可以了:
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
}