我在一段代码中发现了一个奇怪的问题,即即使其参数与数据源中的记录匹配,adhoc SQL查询也没有产生预期的输出.我决定将以下测试表达式输入到即时窗口中:
new SqlParameter("Test", 0).Value
Run Code Online (Sandbox Code Playgroud)
这给了null我一个让我挠头的结果.似乎SqlParameter构造函数将零视为空值.以下代码生成正确的结果:
SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0
Run Code Online (Sandbox Code Playgroud)
谁能解释这种行为?这是故意的吗?如果是这样,它可能相当危险......
有一个:
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?
请考虑以下最小示例:
Module Module1
Private Enum MyEnum
A
End Enum
Public Sub Main(args As String())
AreEqual(CType(0, MyEnum), MyEnum.A) ' Error here
End Sub
Private Function AreEqual(Of T)(item1 As T, item2 As T) As Boolean
Return False
End Function
Private Function AreEqual(item1 As Object, item2 As Object) As Boolean
Return False
End Function
End Module
Run Code Online (Sandbox Code Playgroud)
由于某些奇怪的原因,标记为"Error here"的行中的重载解析失败:
错误6重载决策失败,因为没有可访问的'AreEqual'对这些参数最具体:
Private Function AreEqual(item1 As Object, item2 As Object) As Boolean:不是最具体的.
Private Function AreEqual(Of MyEnum)(item1 As MyEnum, item2 As MyEnum) As Boolean:不是最具体的.
为什么第二个功能不是"最具体"的? …
拿这段代码:
enum En {
val1,
val2,
}
void Main()
{
En plop = 1; //error: Cannot implicitly convert type 'int' to 'En'
En woop = 0; //no error
}
Run Code Online (Sandbox Code Playgroud)
当然它分配失败时1至enum型变量.(打一个明确的演员,它会起作用.)
我的问题是:为什么分配0时不会失败?
试试这个最小的代码:
void Main()
{
Foo test;
test = 0;
test = 1;
Console.WriteLine(test);
}
enum Foo { Bar, Baz }
Run Code Online (Sandbox Code Playgroud)
该行将test = 1抛出一个编译错误,但是这行test = 0很愉快!
CS0266无法将类型'int'隐式转换为'UserQuery.Foo'.存在显式转换(您是否错过了演员?)
编译器版本:Microsoft(R)Visual C#编译器版本1.0.0.50618
为什么我只能指定零值?在任何一种情况下都不应该是一个丢失的施法错误吗?
在使用具有多个采用不同数据类型但没有枚举的重载的外部 API 时,我决定创建一个方便的方法来为枚举提供更多的类型安全性,最终得到如下结果:
namespace TestEnumPromotion
{
enum Values
{
Value0,
Value1,
}
class Program
{
static void Main(string[] args)
{
// Prints int
Overloaded(0);
// Prints Values
Overloaded(Values.Value0);
// Does not compile! :-/
Overloaded((byte) 0);
// Prints int
byte b = 0;
Overloaded(b);
}
static void Overloaded(int i)
{
Console.WriteLine("int");
}
static void Overloaded(Values i)
{
Console.WriteLine("Values");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我很惊讶地发现代码无法编译,因为Overloaded((byte) 0):
以下方法或属性之间的调用不明确:“Program.Overloaded(int)”和“Program.Overloaded(Values)”
但byte不能自动提升为Values,即Values v = (byte)b无法编译,因为:
无法将类型“byte”隐式转换为“TestEnumPromotion.Values”。
所以唯一可能的重载应该是 int,对吗?
我认为枚举可能只是语法糖,编译器会生成接收 int …
c# ×7
enums ×5
.net ×1
ado.net ×1
casting ×1
roslyn ×1
sql-server ×1
sqlparameter ×1
vb.net ×1