简体   繁体   English

C#使用泛型树和表达式树获取对象字段值

[英]C# Use Generics and Expression Trees to get object field values

I have two classes with similar fields: 我有两个具有相似字段的类:

Class Foo {
    string name;
    int val;
};

Class Bar {
    string name;
    int val;
};

Is there a way to use Generics to retrieve the field names and values of objects of these classes? 有没有一种方法可以使用泛型来检索这些类的对象的字段名称和值? Something along the lines of: 类似于以下内容:

string GetName<T> (T obj)
{
    //returns T.name
}

I want to make sure there are compile time checks for this, in case the class fields were to change. 我想确保对此有编译时检查,以防类字段更改。

Update: 更新:

I do not control the definitions of classes Foo and Bar. 我无法控制类Foo和Bar的定义。 They will be exposed to me in a library and can change. 他们将在图书馆中向我公开,并且可以更改。

I can use something like the following: 我可以使用以下内容:

Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);

But I don't think this would check at compile time. 但是我认为这不会在编译时检查。

If you want compile-time safety, and you can't modify Foo and Bar , the typical way to deal with this is with overloads : 如果您需要编译时安全性,并且不能修改FooBar ,则典型的处理方法是重载

public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }

The compiler will automatically pick the method that matches the type of the parameter, so you just need to call it with 编译器将自动选择与参数类型匹配的方法,因此您只需使用

GetName(eitherObject);

...and it's type-safe. ...而且它是类型安全的。

You can't really use generics because Foo and Bar lack a common interface that exposes Name . 您不能真正使用泛型,因为Foo和Bar缺少公开Name的公共接口。

You can use Reflection, of course, but that means abandoning compile-time safety. 当然,您可以使用Reflection,但这意味着放弃编译时安全性。

This seems to be a case where you could use inheritance. 这似乎是可以使用继承的情况。 If these two classes have similar fields you could make them implement a base class which has all the shared fields. 如果这两个类具有相似的字段,则可以使它们实现具有所有共享字段的基类。 Here is an example: 这是一个例子:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM