好的,我有以下基类:
public partial class InputValidator<T> : UserControl {
public InputValidator(TryParse<T> parserMethod, T initialValue) { }
public T Value { get; set; }
public bool IsInputValid { get; }
public override string Text { get; set; }
public string InputInvalidMessage { get; set; }
public TryParse<T> Parser { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
where TryParse<T>是一个委托,它表示类似于TryParse内置类型的所有方法的方法.
public delegate bool TryParse<T>(string input, out T result);
上面的类是一个文本输入控件,它尝试使用指定的解析方法解析用户输入,当它无法解析输入时,它会在文本框下方显示一条消息,指示用户的输入无效.
我现在有以下来自这个类:
public class StructInputValidator<T> : InputValidator<T?> where T : struct
{
public StructInputValidator(TryParse<T> parser, T? initialValue)
: base((string text, out T? result) => {
T nonNullableResult;
bool parseSuccessful = parser(text, out nonNullableResult);
if (!parseSuccessful) result = null;
else result = nonNullableResult;
return parseSuccessful;
},
initialValue) { }
}
Run Code Online (Sandbox Code Playgroud)
上面的类将一个不可为空的结构作为其类型参数并派生自InputValidator<T?>.此派生类的目的是为不可为空的结构采用TryParse方法,并为相应的可空结构提供输入验证器控件,这样当输入无效时,Value属性将设置为null.它的方式是在构造函数中接受TryParse委托,然后将类型为TryParse的lambda表达式传递给基类构造函数.
正如您所看到的,将TryParse<T>委托转换为委托所需的lambda表达式TryParse<T?>足够长,在调用基础构造函数时非常难看.
我的问题是:什么被认为是scenerio中的标准"最佳实践",你在调用这样的基础构造函数时有一个lambda表达式?我无法传递使用Parser属性的实例方法,因为基本构造函数在该属性初始化之前运行.我无法传递一个采用非可空TryParse<T>委托的静态方法,因为它的签名与签名不匹配TryParse<T?>.
是的,那不是很漂亮......但你可以使用一个辅助方法,如下所示:
public class StructInputValidator<T> : InputValidator<T?> where T : struct
{
public StructInputValidator(TryParse<T> parser, T? initialValue)
: base(ToNullableTryParse(parser), initialValue)
{ }
private static TryParse<T?> ToNullableTryParse(TryParse<T> parser)
{
return (string text, out T? result) => {
T nonNullableResult;
bool parseSuccessful = parser(text, out nonNullableResult);
result = parseSuccessful ? (T?)nonNullableResult : null;
return parseSuccessful;
};
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
707 次 |
| 最近记录: |