C# 将属性作为要获取和设置的参数传递

C# 将属性作为要获取和设置的参数传递,c#,pointers,reflection,properties,parameter-passing,C#,Pointers,Reflection,Properties,Parameter Passing,我需要对许多属性重复相同的代码。 我看到过采取行动代理的示例,但它们在这里不太合适 我想要这样的东西:(见下面的解释) 字典属性更正值; public bool CheckValue(Property P){return P.Value==PropertyCorrectValues[P];} public void DoCorrection(Property P){P.Value=PropertyCorrectValues[P];} 我想要一个包含许多属性及其各自的“正确”值的字典。(我知道

我需要对许多属性重复相同的代码。 我看到过采取
行动
代理的示例,但它们在这里不太合适

我想要这样的东西:(见下面的解释)

字典属性更正值;
public bool CheckValue(Property P){return P.Value==PropertyCorrectValues[P];}
public void DoCorrection(Property P){P.Value=PropertyCorrectValues[P];}

我想要一个包含许多属性及其各自的“正确”值的字典。(我知道这不是很好的声明,但这就是想法)。属性在我的类中不是必需的,它们中的一些位于不同程序集的对象中

方法
bool CheckValue(属性)
。此方法必须
访问属性的实际值
,并
比较正确的值

以及方法a
无效文档更正(属性)
。这个
将属性值设置为正确的值

记住,我有很多这样的属性,我不想为每个属性手动调用方法。我宁愿在一个
foreach
语句中遍历diciary


所以,主要问题在标题中

  • 我尝试了ref的
    ,但属性不接受

  • 我是否有义务使用反射???或者还有其他选择(如果我需要,也会接受反思答案)

  • 我能用C语言编写一本带有
    指针的词典吗?或者某种赋值,
    更改变量目标值
    ,而不是
    将目标值更改为另一个值


谢谢您的帮助。

您可以使用反射来完成此操作。使用
typeof(Foo).GetProperties()
获取感兴趣对象的属性列表。您的
PropertyCorrectValues
属性可以具有类型
IDictionary
。然后使用
PropertyInfo
上的
GetValue
SetValue
方法执行所需操作:

public bool CheckProperty(object myObjectToBeChecked, PropertyInfo p) 
{ 
    return p.GetValue(myObjectToBeChecked, null).Equals(PropertyCorrectValues[p]); 
}
public void DoCorrection(object myObjectToBeCorrected, PropertyInfo p) 
{ 
    p.SetValue(myObjectToBeCorrected, PropertyCorrectValues[p]); 
}

除了Ben的代码外,我还想提供以下代码片段:

Dictionary<string,object> PropertyCorrectValues = new Dictionary<string,object>();

PropertyCorrectValues["UserName"] = "Pete"; // propertyName
PropertyCorrectValues["SomeClass.AccountData"] = "XYZ"; // className.propertyName

public void CheckAndCorrectProperties(object obj) {
    if (obj == null) { return; }
    // find all properties for given object that need to be checked
    var checkableProps = from props 
            in obj.GetType().GetProperties()
            from corr in PropertyCorrectValues
            where (corr.Key.Contains(".") == false && props.Name == corr.Key) // propertyName
               || (corr.Key.Contains(".") == true && corr.Key.StartsWith(props.DeclaringType.Name + ".") && corr.Key.EndsWith("." + props.Name)) // className.propertyName
            select new { Property = props, Key = corr.Key };
    foreach (var pInfo in checkableProps) {
        object propValue = pInfo.Property.GetValue(obj, null);
        object expectedValue = PropertyCorrectValues[pInfo.Key];
        // checking for equal value
        if (((propValue == null) && (expectedValue != null)) || (propValue.Equals(expectedValue) == false)) {
            // setting value
            pInfo.Property.SetValue(obj, expectedValue, null);
        }
    }
}
Dictionary PropertyCorrectValues=new Dictionary();
PropertyCorrectValues[“用户名”]=“皮特”//属性名称
PropertyCorrectValues[“SomeClass.AccountData”]=“XYZ”//className.propertyName
公共无效检查和更正属性(对象obj){
如果(obj==null){return;}
//查找需要检查的给定对象的所有属性
var checkableProps=来自props
在obj.GetType().GetProperties()中
从属性correctValues中的corr
其中(corr.Key.Contains(“.”==false&&props.Name==corr.Key)//propertyName
||(corr.Key.Contains(“.”==true&&corr.Key.StartsWith(props.DeclaringType.Name+”)&&corr.Key.EndsWith(“.”+props.Name))//className.propertyName
选择新{Property=props,Key=corr.Key};
foreach(checkableProps中的var pInfo){
object propValue=pInfo.Property.GetValue(obj,null);
object expectedValue=PropertyCorrectValues[pInfo.Key];
//检查值是否相等
如果((propValue==null)和(&(expectedValue!=null))| |(propValue.Equals(expectedValue)==false)){
//设定值
pInfo.Property.SetValue(obj,expectedValue,null);
}
}
}
使用此“自动”值校正时,您还可以考虑:

  • 您不能仅通过知道属性名称并独立于声明类来创建
    PropertyInfo
    对象;这就是我选择
    string
    作为键的原因
  • 在不同的类中使用相同的属性名称时,可能需要更改执行实际赋值的代码,因为正确值和属性类型之间的类型可能不同
  • 在不同的类中使用相同的属性名称将始终执行相同的检查(请参见上面的一点),因此您可能需要属性名称的语法将其限制为特定的类(简单的点表示法,不适用于名称空间或内部类,但可以扩展以执行此操作)
  • 如果需要,您可以用单独的方法调用替换“check”和“assign”部分,但可以在代码块内完成,如我的示例代码中所述

如何定义正确的值?在我看来,这是一种错误的方法。这是在初始化中手动定义的,并且在程序结束时保持不变。或者我可以稍后创建一个外部表来读取属性名和正确的值。无论如何,正确的值都存在。只需要检查并应用它们。很多地方,不止一次。更新和获取更新的属性值。
Dictionary<string,object> PropertyCorrectValues = new Dictionary<string,object>();

PropertyCorrectValues["UserName"] = "Pete"; // propertyName
PropertyCorrectValues["SomeClass.AccountData"] = "XYZ"; // className.propertyName

public void CheckAndCorrectProperties(object obj) {
    if (obj == null) { return; }
    // find all properties for given object that need to be checked
    var checkableProps = from props 
            in obj.GetType().GetProperties()
            from corr in PropertyCorrectValues
            where (corr.Key.Contains(".") == false && props.Name == corr.Key) // propertyName
               || (corr.Key.Contains(".") == true && corr.Key.StartsWith(props.DeclaringType.Name + ".") && corr.Key.EndsWith("." + props.Name)) // className.propertyName
            select new { Property = props, Key = corr.Key };
    foreach (var pInfo in checkableProps) {
        object propValue = pInfo.Property.GetValue(obj, null);
        object expectedValue = PropertyCorrectValues[pInfo.Key];
        // checking for equal value
        if (((propValue == null) && (expectedValue != null)) || (propValue.Equals(expectedValue) == false)) {
            // setting value
            pInfo.Property.SetValue(obj, expectedValue, null);
        }
    }
}