C# 如何在以后设置属性值

C# 如何在以后设置属性值,c#,lambda,ref,C#,Lambda,Ref,我正在寻找一种机制,它允许我仅在满足某些条件时才延迟设置参数的支持字段。我一直在考虑这个设计,直到遇到一个障碍,因为它需要在lambda表达式中使用ref参数。有没有一种方法可以做到这一点,而不需要将ref参数放在lambda中 protectedbool isRunning=false; 列表参数设置器=新列表(); //委托和后续子例程的原因 //是定义一个采用ref参数的操作 受保护的委托void setArgByRef(ref T arg,T value); 受保护的无效集合argByR

我正在寻找一种机制,它允许我仅在满足某些条件时才延迟设置参数的支持字段。我一直在考虑这个设计,直到遇到一个障碍,因为它需要在lambda表达式中使用
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);