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

.net c# expression-trees

Question

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. 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.

1
0
9/13/2018 5:00:32 PM

Accepted Answer

If you want compile-time safety, and you can't modify Foo and Bar, the typical way to deal with this is with overloads:

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.

You can use Reflection, of course, but that means abandoning compile-time safety.

1
9/13/2018 4:46:11 PM

Popular Answer

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
}


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow