开发者

Can I accept both a delegate type T and an Expression<T> in the same parameter?

开发者 https://www.devze.com 2023-01-13 17:47 出处:网络
I\'m trying to write a helper class that represents fields on an object. The helper class needs to be able to both get the value of the field on a given instance AND return metadata about the underlyi

I'm trying to write a helper class that represents fields on an object. The helper class needs to be able to both get the value of the field on a given instance AND return metadata about the underlying property that it can obtain by reflection.

I'd like the helper class be created by a utility method that gets called something like the following:

public IEnumerable<IFieldInfo<SomeType>> Fields {
  get {
    yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeField);
    yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeOtherField);
  }
}

Say that the IFieldInfo interface looks a bit like this:

interface IFieldInfo<in T> {
  public string PropertyName {get;}
  public object GetValue(T obj);
}

In the context of my application, the Fields property will be accessed fairly often; the GetValue() method will be called fairly often, but the PropertyName (and the other metadata/reflectiony fields that I omitted for clarity) will be accessed less frequently. There are a lot of places where the Fields property needs to be implemented, and sometimes a lot of fields, so it's important for code clarity and maintenance that the code that calls GetFieldInfo be simple and clear; duplicating the list of fields or duplicating the parameter would be just asking for bugs where they get out of sync.

So, how do I write GetFieldInfo? If I do:

开发者_开发百科
public static IFieldInfo<T> GetFieldInfo<T>(Func<T, object> getter);

then I can implement GetValue() trivially by calling getter(obj) but I have no way to access the name.

If, on the other hand, I do:

public static IFieldInfo<T> GetFieldInfo<T>(Expression<Func<T, object>> getter)

then I can extract the name of the property access that's represented by the expression, but the only way to implement GetValue() is to call Compile() on the expression, which I imagine to be a ridiculous amount of overhead for something that the compiler itself could compile for me, especially since GetValue() is used more often on these objects than PropertyName is.

Is there any way to write my GetFieldInfo helper function to take a single parameter and interpret it as both an expression tree AND a delegate without the overhead of compiling the expression tree into a delegate at runtime?


I can't see any way that would be possible. The delegate and the Expression are two different object type, which just happen to look alike. It would be akin to writing:

  MyFunc("10m");

And having the paramter treated as both a string and as a decimal without doing any conversion.

Your best bet would be to call Compile() and caching the result. I assume you were already planning on caching the result of searching through the Expression for the property Name.

0

精彩评论

暂无评论...
验证码 换一张
取 消