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

时间:2013-05-08 21:55:10

标签: c# pointers reflection properties parameter-passing

好吧,我需要为许多属性重复相同的代码。 我见过代表Action代表的例子,但是它们在这里并不适合。

我想要这样的事情:(见下面的解释)

Dictionary<Property, object> PropertyCorrectValues;
public bool CheckValue(Property P) { return P.Value == PropertyCorrectValues[P]; }
public void DoCorrection(Property P) { P.Value = PropertyCorrectValues[P]; }    

我想要一个包含许多属性及其各自“正确”值的字典。 (我知道它没有很好地宣布,但这是个主意)。属性不是我班级内部必需的,其中一些属于不同组件的对象。

方法bool CheckValue(Property)。此方法必须access the actual value属性compare to the correct value

方法a void DoCorrection(Property)。这一个sets the property value到正确的值。

请记住我有很多这些属性,我不想为每个属性手动调用这些方法。我宁愿在foreach陈述中迭代这个词典。


所以,主要问题在于标题。

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

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

  • 我是否可以在C#中使用pointers制作字典?或某种changes the value of variable's target代替changing the target to another value

  • 的作业

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以使用反射来完成此操作。使用typeof(Foo).GetProperties()获取感兴趣对象的属性列表。您的PropertyCorrectValues媒体资源可以包含IDictionary<PropertyInfo, object>类型。然后使用GetValue上的SetValuePropertyInfo方法执行所需的操作:

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]); 
}

答案 1 :(得分:0)

除了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);
        }
    }
}

使用此“自动”值修正时,您可能还会考虑:

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