有一个:
enum SomeEnum
{
A = 0,
B = 1,
C = 2
}
Run Code Online (Sandbox Code Playgroud)
现在编译器允许我写:
SomeEnum x = SomeEnum.A;
switch(x)
{
case 0: // <--- Considered SomeEnum.A
break;
case SomeEnum.B:
break;
case SomeEnum.C:
break;
default:
break;
}
Run Code Online (Sandbox Code Playgroud)
0被认为SomeItems.A.但我写不出来:
SomeEnum x = SomeEnum.A;
switch(x)
{
case 0:
break;
case 1: // <--- Here is a compilation error.
break;
case SomeEnum.C:
break;
default:
break;
}
Run Code Online (Sandbox Code Playgroud)
为什么只存在隐式转换0?
首先,有点背景.阅读此处发布的问题和已接受的答案,以了解我的问题的具体方案.我不确定是否存在其他相似的案例,但这是我所知道的唯一案例.
上面的"怪癖"是我早已意识到的.直到最近,我才明白原因的全面性.
微软关于这个SqlParameter课程的文档对这种情况有了更多的了解.
Object在value参数中指定a 时,SqlDbType将从Object的Microsoft .NET Framework类型推断出.使用
SqlParameter构造函数的此重载指定整数参数值时请小心.因为此重载采用type的值Object,所以必须在值为零时将整数值转换为Object类型,如下面的C#示例所示.
Parameter = new SqlParameter("@pname", Convert.ToInt32(0));如果不执行此转换,编译器会假定您尝试调用SqlParameter(string,SqlDbType)构造函数重载.
(emph.补充)
我的问题是为什么编译器假设当你指定硬编码"0"(并且只有值"0")时,你试图指定枚举类型而不是整数类型?在这种情况下,它假定您声明SqlDbType值,而不是值0.
这是非直观的,更糟糕的是,错误是不一致的.我有一些旧的应用程序,我已经编写了多年来调用存储过程.我将对应用程序进行更改(通常甚至与我的SQL Server类无关),发布更新,这个问题会突然中断应用程序.
当包含多个方法签名的对象包含两个相似的签名时,为什么编译器会被值0混淆,其中一个参数是对象/整数而另一个接受枚举?
正如我所提到的,我从未将其视为任何其他类的任何其他构造函数或方法的问题.这是SqlParameter该类的独特之处还是这是一个在C#/ .Net中继承的bug?
我有以下存储过程
CREATE PROCEDURE [dbo].[usp_GetData]
@foo VARCHAR (20), @bar bit = 1
AS ...
Run Code Online (Sandbox Code Playgroud)
这在SSMS中调用时提供了正确的结果.
EXEC dbo.usp_GetData @foo = 'Hellow World', @bar = 0
Run Code Online (Sandbox Code Playgroud)
虽然在C#应用程序中调用如下所示
cmd.Parameters.Add(new SqlParameter("@foo", foo));
cmd.Parameters.Add(new SqlParameter("@bar", 0));
Run Code Online (Sandbox Code Playgroud)
&由剖析器捕获,如下所示.
exec dbo.usp_GetData @foo=N'Hello World',@bar=default
Run Code Online (Sandbox Code Playgroud)
是否必须以不同方式传递超出默认值的参数?