我一直在代码中遇到对相同模式的需求,这经常需要验证对象中所有属性的值。伪代码如下所示:
bool ValidateMe(object c) {
var properties = GetProperties(c);
foreach (var property in properties) {
var value = property.GetValue(c);
if (!IsValid(value)) {
return false;
}
}
return true;
}
bool IsValid(int value)
{
return value != int.MaxValue;
}
bool IsValid(double value)
{
return value != double.MaxValue;
}
bool IsValid(object value)
{
return value != null;
} // etc.
Run Code Online (Sandbox Code Playgroud)
我希望代码根据对象的类型(可以通过调用property.PropertType或value.GetType()假设值不为空来找到)动态地将值分派到正确的方法。
我发现实现这项工作的唯一方法是这样的:
interface IValidator {
bool IsValid(object value);
}
class PredicateValidator<T> : IValidator {
private Predicate<T> method;
PredicateValidator(Predicate<T> method) {
this.method = method;
}
bool IsValid(object value) {
return IsValid((T) value);
}
bool IsValid(T value) {
return method.invoke(value);
}
}
var validationsByType = new Dictionary<Type,IValidator>();
validationsByType[typeof(double)]=new PredicateValidator<double>(IsValid);
validationsByType[typeof(double)]=new PredicateValidator<int>(IsValid);
Run Code Online (Sandbox Code Playgroud)
然后 Map 可以按类型将对象分派到正确的方法:
object value = property.GetValue(c);
bool result = validationsByType[c.GetType()].IsValid(value);
Run Code Online (Sandbox Code Playgroud)
是否有原生 C#(即语言功能)可以在运行时按类型进行动态分派?
该dynamic关键字将正确执行向下转换。所以上面的代码修改为:
bool ValidateMe(object c) {
var properties = GetProperties(c);
foreach (var property in properties) {
var value = property.GetValue(c);
if (!IsValid((dynamic) value)) {
return false;
}
}
return true;
}
bool IsValid(int value)
{
return value != int.MaxValue;
}
bool IsValid(double value)
{
return value != double.MaxValue;
}
Run Code Online (Sandbox Code Playgroud)
然后,.NET 运行时搜索要调用的最具体的方法签名。我之前认为这只dynamic适用于Duck Typing,但它也适用于动态分派到重载方法。
| 归档时间: |
|
| 查看次数: |
2717 次 |
| 最近记录: |