C# 请求表达式时防止隐式强制转换为int<;Func<;T、 十进制>&燃气轮机;

C# 请求表达式时防止隐式强制转换为int<;Func<;T、 十进制>&燃气轮机;,c#,C#,因此,int可以隐式转换为decimal。当需要十进制属性的表达式时,这会导致问题,其中传递具有隐式强制转换的int属性的表达式。由于隐式强制转换,没有给出编译器错误 例如: 类的东西{ 公共int属性{get;set;} } 无效剂量( 表达pDecimalExpression ) { ... } DoSomething(t=>t.IntProperty);//编辑;IntProperty隐式转换为十进制 有没有一种方法可以在编译时确保我真的得到一个decimal属性?如果我像这样传递一个带

因此,
int
可以隐式转换为
decimal
。当需要
十进制
属性的
表达式
时,这会导致问题,其中传递具有隐式强制转换的
int
属性的
表达式
。由于隐式强制转换,没有给出编译器错误

例如:

类的东西{
公共int属性{get;set;}
}
无效剂量(
表达pDecimalExpression
) {
...
}
DoSomething(t=>t.IntProperty);//编辑;IntProperty隐式转换为十进制
有没有一种方法可以在编译时确保我真的得到一个
decimal
属性?如果我像这样传递一个带有隐式强制转换的表达式,我希望编译器出现错误


(由于我使用的是反射,我最终遇到一个运行时错误,说我使用的属性不能被赋予
decimal
值。我觉得我能做的最好的事情就是在运行时自己检测类型不匹配,并抛出一个稍微好一点的错误。)。编译器更喜欢使用
int
的重载,因此提供一个重载并使用发出编译时错误的功能

像这样声明
DoSomething

void DoSomething(Expression<Func<Thing, decimal>> pDecimalExpression)
{
    // …
}

[Obsolete("No, no, no!", true)] // the true here causes an error instead of a warning
void DoSomething(Expression<Func<Thing, int>> pIntExpression)
{
    // just in case someone would call this method via reflection
    throw new NotSupportedException();
}

我会使用泛型约束。由于不能直接使用结构类型,您仍然可以使用
IEquatable
来限制可以作为
T
传递的内容(内置类型实现此接口)。缺点是,任何实现
IEquatable
的东西都将被允许作为
T
通用参数(在您的情况下可能会有问题,也可能不会有问题)

void DoSomething(表达式pDecimalExpression)
其中T:struct,i可满足{
...
}

第二个选项是编写自定义Roslyn分析器,以便在编译时验证代码


希望有帮助。

谢谢!我曾想过重载,但只想到调用另一个仍然可以强制转换的版本(如果我可以调用的话),或者只是抛出一个已经发生的异常。我最终选择了这种方法。我不喜欢让我的方法变得不必要的泛化,我还必须在
t
decimal
之间进行转换,但这样做更好,不必编写额外的方法。你到底在处理什么?我可以看看它,希望能给你一个更新来解决它。我用这里找到的解决方案解决了转换问题:@DaveCousineau:我现在坐在上面。给我更多的上下文。您只需要设置值,否则还有其他事情要做?我没有进一步的问题。这很有效。我不喜欢这些方法是通用的,但它肯定比以前好。现在一切正常,如果我提供一个
int
属性,我将得到一个编译器错误。
void DoSomething(Expression<Func<Thing, decimal>> pDecimalExpression)
{
    // …
}

[Obsolete("No, no, no!", true)] // the true here causes an error instead of a warning
void DoSomething(Expression<Func<Thing, int>> pIntExpression)
{
    // just in case someone would call this method via reflection
    throw new NotSupportedException();
}
DoSomething(t => t.IntProperty);
void DoSomething<T>(Expression<Func<Thing, T>> pDecimalExpression)
    where T : struct, IEquatable<decimal> {
    ...
}