C# 使用泛型和表达式树获取对象字段值
C# Use Generics and Expression Trees to get object field values
我有两个 class 字段相似:
Class Foo {
string name;
int val;
};
Class Bar {
string name;
int val;
};
有没有办法使用泛型来检索这些 classes 的对象的字段名称和值?大致如下:
string GetName<T> (T obj)
{
//returns T.name
}
我想确保对此进行编译时检查,以防 class 字段发生变化。
更新:
我不控制 classes Foo 和 Bar 的定义。他们将在图书馆向我展示并且可以更改。
我可以使用类似下面的东西:
Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);
但我认为这不会在编译时进行检查。
这似乎是您可以使用继承的情况。如果这两个 class 具有相似的字段,您可以让它们实现一个具有所有共享字段的基础 class。这是一个例子:
public class BaseEntity
{
int val;
protected string name;
public string Name
{
get
{
return name; // Only get is exposed to prevent modifications
}
}
}
public class ClassA : BaseEntity
{
// Other fields or methods
}
public class ClassB : BaseEntity
{
// Other fields or methods
}
如果你想要编译时安全,并且你不能修改Foo
和Bar
,典型的处理方法是overloads:
public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }
编译器会自动选择与参数类型匹配的方法,所以你只需要用
调用它
GetName(eitherObject);
...而且它是类型安全的。
您不能真正使用泛型,因为 Foo 和 Bar 缺少公开的通用接口 Name
。
你当然可以使用反射,但这意味着放弃编译时安全。
我有两个 class 字段相似:
Class Foo {
string name;
int val;
};
Class Bar {
string name;
int val;
};
有没有办法使用泛型来检索这些 classes 的对象的字段名称和值?大致如下:
string GetName<T> (T obj)
{
//returns T.name
}
我想确保对此进行编译时检查,以防 class 字段发生变化。
更新:
我不控制 classes Foo 和 Bar 的定义。他们将在图书馆向我展示并且可以更改。
我可以使用类似下面的东西:
Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);
但我认为这不会在编译时进行检查。
这似乎是您可以使用继承的情况。如果这两个 class 具有相似的字段,您可以让它们实现一个具有所有共享字段的基础 class。这是一个例子:
public class BaseEntity
{
int val;
protected string name;
public string Name
{
get
{
return name; // Only get is exposed to prevent modifications
}
}
}
public class ClassA : BaseEntity
{
// Other fields or methods
}
public class ClassB : BaseEntity
{
// Other fields or methods
}
如果你想要编译时安全,并且你不能修改Foo
和Bar
,典型的处理方法是overloads:
public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }
编译器会自动选择与参数类型匹配的方法,所以你只需要用
调用它GetName(eitherObject);
...而且它是类型安全的。
您不能真正使用泛型,因为 Foo 和 Bar 缺少公开的通用接口 Name
。
你当然可以使用反射,但这意味着放弃编译时安全。