Если нет более простых ответов, я бы попробовал это с этим.
Вы можете использовать выражения примерно так:
// Sample object with a property.
SomeClass someClass = new SomeClass{Property = "Value"};
// Create the member expression.
Expression<Func<object /*prop owner object*/, object/*prop value*/>> e =
owner => ((SomeClass)owner).Property;
// Get property name by analyzing expression.
string propName = ((MemberExpression)e.Body).Member.Name;
// Get property value by compiling and running expression.
object propValue = e.Compile().Invoke(someClass);
Вы передаете свою собственность участникувыражение owner => ((SomeClass)owner).Property
.Это выражение содержит необходимую информацию: имя свойства и значение свойства.Последние две строки показывают, как получить имя и значение.
Следуя большему примеру :
class MainClass
{
public static void Execute()
{
SomeClass someClass = new SomeClass{
Property = "Value"
};
var search = new ClassSearch(s => ((SomeClass)s).Property);
Console.Out.WriteLine("{0} = '{1}'", search.Property.Name, search.Property.GetValue(someClass));
}
}
class Reflector
{
public static string GetPropertyName(Expression<Func<object, object>> e)
{
if (e.Body.NodeType != ExpressionType.MemberAccess)
{
throw new ArgumentException("Wrong expression!");
}
MemberExpression me = ((MemberExpression) e.Body);
return me.Member.Name;
}
}
class ClassSearch
{
public ClassSearch(Expression<Func<object, object>> e)
{
Property = new PropertyNameAndValue(e);
}
public PropertyNameAndValue Property { get; private set; }
public override string ToString()
{
return String.Format("{0} = '{1}'", Property.Name, Property);
}
}
class PropertyNameAndValue
{
private readonly Func<object, object> _func;
public PropertyNameAndValue(Expression<Func<object, object>> e)
{
_func = e.Compile();
Name = Reflector.GetPropertyName(e);
}
public object GetValue(object propOwner)
{
return _func.Invoke(propOwner);
}
public string Name { get; private set; }
}
class SomeClass
{
public string Property { get; set; }
}
Основной частью этого примера является метод Reflector.GetPropertyName(...)
, который возвращаетимя свойства в выражении.Т.е. Reflector.GetPropertyName(s => ((SomeClass)s).Property)
вернул бы «Свойство».
Преимущество : Это типобезопасно, потому что при new ClassSearch(s => s.Property)
компиляция завершится ошибкой, если SomeClass не будет иметь свойства 'Property
'.
Недостаток : Это небезопасно, потому что если вы напишите, например, new ClassSearch(s => s.Method())
и там будетбудь метод 'Method
', тогда не будет ошибки компиляции, но будет ошибка времени выполнения.