我想做的是:
GetString(
inputString,
ref Client.WorkPhone)
private void GetString(string inValue, ref string outValue)
{
if (!string.IsNullOrEmpty(inValue))
{
outValue = inValue;
}
}
这给了我一个编译错误。我想我想达到的目的已经很清楚了。基本上我想要GetString复制输入字符串的内容到客户端的WorkPhone属性。
是否可以通过引用传递属性?
我用ExpressionTree变体和c#7写了一个包装器(如果有人感兴趣的话):
public class Accessor<T>
{
private Action<T> Setter;
private Func<T> Getter;
public Accessor(Expression<Func<T>> expr)
{
var memberExpression = (MemberExpression)expr.Body;
var instanceExpression = memberExpression.Expression;
var parameter = Expression.Parameter(typeof(T));
if (memberExpression.Member is PropertyInfo propertyInfo)
{
Setter = Expression.Lambda<Action<T>>(Expression.Call(instanceExpression, propertyInfo.GetSetMethod(), parameter), parameter).Compile();
Getter = Expression.Lambda<Func<T>>(Expression.Call(instanceExpression, propertyInfo.GetGetMethod())).Compile();
}
else if (memberExpression.Member is FieldInfo fieldInfo)
{
Setter = Expression.Lambda<Action<T>>(Expression.Assign(memberExpression, parameter), parameter).Compile();
Getter = Expression.Lambda<Func<T>>(Expression.Field(instanceExpression,fieldInfo)).Compile();
}
}
public void Set(T value) => Setter(value);
public T Get() => Getter();
}
像这样使用它:
var accessor = new Accessor<string>(() => myClient.WorkPhone);
accessor.Set("12345");
Assert.Equal(accessor.Get(), "12345");
只是对内森的Linq表达式解决方案的一点扩展。使用多泛型参数,使属性不限于字符串。
void GetString<TClass, TProperty>(string input, TClass outObj, Expression<Func<TClass, TProperty>> outExpr)
{
if (!string.IsNullOrEmpty(input))
{
var expr = (MemberExpression) outExpr.Body;
var prop = (PropertyInfo) expr.Member;
if (!prop.GetValue(outObj).Equals(input))
{
prop.SetValue(outObj, input, null);
}
}
}