C# 如何在以后设置属性值
我正在寻找一种机制,它允许我仅在满足某些条件时才延迟设置参数的支持字段。我一直在考虑这个设计,直到遇到一个障碍,因为它需要在lambda表达式中使用C# 如何在以后设置属性值,c#,lambda,ref,C#,Lambda,Ref,我正在寻找一种机制,它允许我仅在满足某些条件时才延迟设置参数的支持字段。我一直在考虑这个设计,直到遇到一个障碍,因为它需要在lambda表达式中使用ref参数。有没有一种方法可以做到这一点,而不需要将ref参数放在lambda中 protectedbool isRunning=false; 列表参数设置器=新列表(); //委托和后续子例程的原因 //是定义一个采用ref参数的操作 受保护的委托void setArgByRef(ref T arg,T value); 受保护的无效集合argByR
ref
参数。有没有一种方法可以做到这一点,而不需要将ref参数放在lambda中
protectedbool isRunning=false;
列表参数设置器=新列表();
//委托和后续子例程的原因
//是定义一个采用ref参数的操作
受保护的委托void setArgByRef(ref T arg,T value);
受保护的无效集合argByRefSub(参考T参数,T值)
{
arg=值;
}
受保护的int_设定点;
公共整数设定点
{
获取{返回_设置点;}
设置{setValue(参考设定点,值);}
}
公开募捐
{
isRunning=true;
//这里的代码非常耗时
//不希望允许设定点更改
//正在运行时==true
isRunning=false;
//设置设定点和其他属性
argumentSetters.ForEach((a)=>a.Invoke());
}
受保护的无效设置值(参考T参数,T值)
{
setArgByRef a=新的setArgByRef(setArgByRefSub);
如果(正在运行)
//无法在lambda中使用ref参数
{argumentSetters.Add(()=>a.Invoke(ref-arg,value));}
其他的
{arg=value;}
}
我能想到的最佳解决方案是使用表达式。这里的想法是存储属性持有对象、属性信息和要设置的值,然后在准备就绪时设置它们
从我写的另一个函数中提取一点,您可以使用一个函数从表达式中获取PropertyInfo
:
public static PropertyInfo GetPropertyInfo<TIn, TOut>(Expression<Func<TIn, TOut>> PropertyExpression)
{
MemberExpression memberExpr;
switch (PropertyExpression.Body.NodeType)
{
case ExpressionType.MemberAccess:
memberExpr = (MemberExpression)PropertyExpression.Body;
break;
case ExpressionType.Convert:
memberExpr = (MemberExpression)((UnaryExpression)PropertyExpression.Body).Operand;
break;
default:
throw new NotSupportedException();
}
var property = (PropertyInfo)memberExpr.Member;
return property;
}
当然,您也可以拉出obj
参数,只要使用this
,如果这更合适的话。如果这变成了现实世界的代码,我会很想不使用Tuple
,因为它有点凌乱,但我在这里使用它是为了使这个示例最小化和完整。当然,这两种方法都应该奏效
这样做的问题是,它在您正在使用的字段上不起作用,但是您可以设置一个属性并使用this
,这样应该可以。也许还有一种方法可以使表达式与字段一起工作,我只是从来没有必要这样做,所以我不确定
为了更好地衡量,您可以这样调用AddPendingState
方法。我编了一个TypeA
作为例子
AddPendingState<TypeA, int>(instance, c => c.PropertyName, 2);
AddPendingState(实例,c=>c.PropertyName,2);
您可以使用()=>\u setPoint=value
操作lambda吗?不在setValue()内,因为这是特定于\u setPoint的,而我想使用setValue的原因是因为这是一个抽象类,所以我想让属性setter内的实现保持最小。SetPoint只是一个例子,在派生类中会定义更多的道具,它们应该以相同的方式处理。我曾考虑过使用反射,但我没有想到表达式。我会试试看。
public static void AddPendingSet<TType, TProperty>(TType obj, Expression<Func<TType, TProperty>> expr, TProperty val)
{
var prop = GetPropertyInfo(expr);
_ToSet.Add(new Tuple<object, PropertyInfo, object>(obj, prop, val);
}
foreach (var v in _ToSet)
{
v.Item2.SetValue(v.Item1, v.Item3);
}
AddPendingState<TypeA, int>(instance, c => c.PropertyName, 2);