如何重写此代码块
本文关键字:代码 重写 何重写 | 更新日期: 2023-09-27 18:27:25
我有一个类有大约40个属性(我对此没有发言权,这是根据规范)。所有属性都有自定义的"set"方法。
有一个有点复杂的验证,我必须把它强加给所有的"集合"方法。我已经将验证分离为一个单独的方法,我们称之为
CCD_ 1。
到目前为止,我从每个单独的"集合"方法中调用这个验证方法,如下所示:
public string Property1
{
set
{
this.field1 = value;
CommonValidate(Property1, this.field1);
}
}
public DateTime Property2
{
set
{
this.field2 = value.ToString("ddMMyy");;
CommonValidate(Property2, this.field2);
}
}
public string Property3
{
set
{
this.field3 = value;
CommonValidate(Property3, this.field3);
}
}
通过这种方式,我刚刚在所有40个"set"方法中粘贴了CommonValidate方法调用。我发现这是非常无效的,想象一下,如果有对CommonValidate方法中参数数量的更改请求。
有没有其他方法可以把它改成更好的模式?
您可以使用反射来获得一个函数,该函数以属性和新值的名称传递。它进行验证,然后使用值执行正常设置。反射在速度方面效率不高,但对重用代码非常有用。进行一些诊断,以确保损失的时间在您可接受的范围内。
void ValidateAndSet(string propName, object newValue){
foreach(var prop in propsClass.GetType().GetProperties().Where(p => p.Name == propName))
{
if(CommonValidate(prop, newValue))
prop.GetSetMethod().Invoke(propsClass, new object[] { newValue});
return; // Only one anyways
}
Logger.Log("Failed to find the property '{0}' to set '{1}'", propName, newValue);
}
propsClass是属性所在的类对象。可以在类中执行此操作,也可以将其作为另一个参数在函数中传递。
有人已经提到了动态类,我不熟悉它们,但简短的阅读会让它们听起来对您的问题很有吸引力。
然而,如果您不走这条路,我会改变的一件事是在CommonValidate
中使用字符串,而使用System.Linq.Expression
。
我会把它重写成这样:
static void CommonValidate<T>(Expression<Func<MyClass, T>> propertySelector, T newValue) //replace MyClass with name of current class
{
MemberExpression memberExpression = propertySelector.Body as MemberExpression;
if (memberExpression == null)
throw new ArgumentException("propertySelector")
string propertyName = MemberExpression.Member.Name;
//validation code, e.g.
CommonValidate(propertyName, newValue.ToString())
}
然后二传手会看起来像
public string Property1
{
set
{
this.field1 = value;
CommonValidate(c => c.Property1, value);
}
}
这样做的好处是,如果更改类上属性的名称,则不更改CommonValidate
调用将成为编译时错误。如果你真的走了这条路,你应该使用类似的东西来设置你的验证:我假设你在某个地方有一个构造函数来填充Dictionary<string, Func<string, bool>
——使用类似于上面新的CommonValidate
中的代码来获取属性名称键。