Eri*_*ric 3 c# generics type-inference
我试图将编译时检查添加到以前使用数据对象属性的字符串名称和'object'类型的值的代码中。我这样做是为了确保属性和值实际上是相同的类型,以防止它们不引入运行时错误的情况。
我正在通过创建一个接受type表达式和type Expression<Func<TDataObject, TPropertyValue>>参数的方法来处理编译时检查TPropertyValue。由此,我可以检查表达式以获取将要返回的属性的名称,然后使用与字符串和值作为对象类型的当今相同的逻辑。
public interface IPropertyDictionary<TDataObject> where TDataObject : class
{
void AddIfSameType<TProperty>(
Expression<Func<TDataObject, TProperty>> propertyAccessExpression,
TProperty propertyValue);
}
Run Code Online (Sandbox Code Playgroud)
预期的工作如下:
// Allowed
propDictionary.AddIfSameType(e => e.IntProperty, 123);
// Flagged by intellisense (though the expression is flagged rather than second parameter...)
propDictionary.AddIfSameType(e => e.IntProperty, "asdf");
Run Code Online (Sandbox Code Playgroud)
但是,这不能按预期方式工作:
// Not flagged as error
propDictionary.AddIfSameType(e => e.IntProperty, 123L);
Run Code Online (Sandbox Code Playgroud)
这样,C#推断TPropertyValue是long而不是int。在调试器中,我可以看到表达式已被转换为强制转换为长整型:
e => Convert(e.IntProperty)
Run Code Online (Sandbox Code Playgroud)
在我的理想情况下,C#在进行类型推断时会更喜欢IntProperty的类型,并引发编译时错误,指示从long到int的转换需要显式转换。有没有办法向C#指示在推断类型时,它仅应使用方法的第一个参数?我目前唯一的选择是显式提供type参数:
// Flagged by intellisense
propDictionary.AddIfSameType<int>(e => e.IntProperty, 123L);
Run Code Online (Sandbox Code Playgroud)
但是在99%的情况下,人们不会传递类型参数,并且我不希望他们意识到在这种情况下需要这样做。结果,它们的错误再次成为我渴望避免的运行时错误之一。
是的,以稍微绕行的方式。使用两个类型参数和一个 类型参数约束。没有相等约束,但是继承约束应适用于大多数情况:
static void AddIfSameType<TLProp,TRProp>(Func<DataObject,TLProp> lprop, TRProp rprop) where TRProp : TLProp
{
}
static void Main(string[] args)
{
AddIfSameType(d => d.IntProperty, 1);
//compiles
AddIfSameType(d => d.IntProperty, 1L);
//Error CS0315 The type 'long' cannot be used as type parameter 'TRProp'
//... There is no boxing conversion from 'long' to 'int'.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |