|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
CLR Bug ?!I suspect a CLR Bug. Please look like this code fragment ! My question is: why 0 (zero) is a special value in CLR ?! Thanks all. Code: using System; namespace CLR_Bug { class MainClass { [STAThread] static void Main(string[] args) { TestClass mytestclass0=new TestClass(0); //Constructor with SimpleEnum was called ! TestClass mytestclass1=new TestClass(1); //Constructor with object was called ! TestClass mytestclassneg1=new TestClass(-1); //Constructor with object was called ! TestClass mytestclass1000=new TestClass(1000);//Constructor with object was called ! TestClass mytestclassStr=new TestClass("a"); //Constructor with object was called ! Console.WriteLine("Why this behaviour ?!"); Console.ReadLine(); //Why 0 is a special value ? } } class TestClass { public enum SimpleEnum { Red = 0, Blue = 1, Yellow = 2 } public TestClass(SimpleEnum se) { Console.WriteLine("Constructor with SimpleEnum was called !"); } public TestClass(object obj) { Console.WriteLine("Constructor with object was called !"); } } } >My question is: why 0 (zero) is a special value in CLR ?! This isn't a CLR issue. It's a C# compiler feature, since methodoverload resolution is performed at compile time. And the reason is that the literal 0 is implicitly convertible to any enum type. Mattias -- Mattias Sjögren [MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. Hi Mattias,
thank you for your answer. I don't think this is compiler feature for 2 reasons: 1) i know that .NET framework resolvs Calls for overloaded methods (with object parameter) at run-time and not at compile time (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/vblrfvbspec9_3_4.asp) 2) i have tried same test with VB.NET with same results. It is a vb.net compiler feature too ?! Thanks in advance. this is VB.NET code i tried: Imports System Module Module1 Sub Main() Dim mytestclass0 As New TestClass(0) 'Constructor with SimpleEnum was called ! Dim mytestclass1 As New TestClass(1) 'Constructor with object was called ! Dim mytestclassneg1 As New TestClass(-1) 'Constructor with object was called ! Dim mytestclass1000 As New TestClass(1000) 'Constructor with object was called ! Dim mytestclassStr As New TestClass("a") 'Constructor with object was called ! Console.WriteLine("Why this behaviour ?!") Console.ReadLine() 'Why 0 is a special value ? End Sub End Module Class TestClass Public Enum SimpleEnum Red = 0 Blue = 1 Yellow = 2 End Enum Public Sub New(ByVal se As SimpleEnum) Console.WriteLine("Constructor with SimpleEnum was called !") End Sub Public Sub New(ByVal obj As Object) Console.WriteLine("Constructor with object was called !") End Sub End Class you wrote: "reason is that the literal 0 is implicitly convertible to any enum type". Ok ... but why this behaviour only for 0 (zero) and not for 1 (one) !? They are both int ! Show quoteHide quote "Mattias Sjögren" wrote: > > >My question is: why 0 (zero) is a special value in CLR ?! > > This isn't a CLR issue. It's a C# compiler feature, since method > overload resolution is performed at compile time. > > And the reason is that the literal 0 is implicitly convertible to any > enum type. > > > > Mattias > > -- > Mattias Sjögren [MVP] mattias @ mvps.org > http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com > Please reply only to the newsgroup. > Andrea <And***@discussions.microsoft.com> wrote:
> Hi Mattias, That's not true in general. Use ildasm to look at the generated code, > > thank you for your answer. > > I don't think this is compiler feature for 2 reasons: > 1) i know that .NET framework resolvs Calls for overloaded methods (with > object parameter) at run-time and not at compile time and you'll see exactly what method is going to be invoked in your case. > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbl That is talking about the case where strict semantics are not being > s7/html/vblrfvbspec9_3_4.asp) used, which isn't even available as an option in C#, so can't possibly apply to the C# code you posted. It's not normally applicable to well- written VB.NET code either, as most VB.NET code should have Option Strict turned on. > 2) i have tried same test with VB.NET with same results. It is a vb.net Yes. In both languages, there's an implicit conversion from the literal > compiler feature too ?! 0 to any enum. (See section 8.8 of the VB.NET spec, and 13.1.3 of the ECMA C# spec.) > you wrote: There are various times when it's useful to have such an implicit > "reason is that the literal 0 is implicitly convertible to any enum type". > > Ok ... but why this behaviour only for 0 (zero) and not for 1 (one) !? > > They are both int ! conversion - not least when checking for bitwise flags: if ((testValue & MyEnum.SomeFlag) != 0) is simpler than if ((testValue & MyEnum.SomeFlag) != (MyEnum)0) and is still perfectly clear. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too Hi Jon,
please look this code: SqlParameter p0=new SqlParameter("@myparam0",0); //produce new SqlParameter("@myparam",SqlDbType.BigInt) with DBNull as parameter's Value //BigInt because SqlDbType.BigInt is the first value in SqlDbType enum SqlParameter p1=new SqlParameter("@myparam1",1); //produce new SqlParameter("@myparam",1) with 1 as paramter's Value and Int as SqlDbType if VB.NET and C# compilers has this behaviour ... If there's an implicit conversion from the literal 0 to enum ... if i try to use p0.Value in this case i have i logical bug ... i receive an unexpeted NullReferenceExpetion Thank you. Andrea. Show quoteHide quote "Jon Skeet [C# MVP]" wrote: > Andrea <And***@discussions.microsoft.com> wrote: > > Hi Mattias, > > > > thank you for your answer. > > > > I don't think this is compiler feature for 2 reasons: > > 1) i know that .NET framework resolvs Calls for overloaded methods (with > > object parameter) at run-time and not at compile time > > That's not true in general. Use ildasm to look at the generated code, > and you'll see exactly what method is going to be invoked in your case. > > > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbl > > s7/html/vblrfvbspec9_3_4.asp) > > That is talking about the case where strict semantics are not being > used, which isn't even available as an option in C#, so can't possibly > apply to the C# code you posted. It's not normally applicable to well- > written VB.NET code either, as most VB.NET code should have Option > Strict turned on. > > > 2) i have tried same test with VB.NET with same results. It is a vb.net > > compiler feature too ?! > > Yes. In both languages, there's an implicit conversion from the literal > 0 to any enum. (See section 8.8 of the VB.NET spec, and 13.1.3 of the > ECMA C# spec.) > > > you wrote: > > "reason is that the literal 0 is implicitly convertible to any enum type". > > > > Ok ... but why this behaviour only for 0 (zero) and not for 1 (one) !? > > > > They are both int ! > > There are various times when it's useful to have such an implicit > conversion - not least when checking for bitwise flags: > > if ((testValue & MyEnum.SomeFlag) != 0) > > is simpler than > > if ((testValue & MyEnum.SomeFlag) != (MyEnum)0) > > and is still perfectly clear. > > -- > Jon Skeet - <sk***@pobox.com> > http://www.pobox.com/~skeet > If replying to the group, please do not mail me too > Andrea <And***@discussions.microsoft.com> wrote:
> please look this code: Which they do.> > SqlParameter p0=new SqlParameter("@myparam0",0); > //produce new SqlParameter("@myparam",SqlDbType.BigInt) with DBNull as > parameter's Value > //BigInt because SqlDbType.BigInt is the first value in SqlDbType enum > SqlParameter p1=new SqlParameter("@myparam1",1); > //produce new SqlParameter("@myparam",1) with 1 as paramter's Value and Int > as SqlDbType > > if VB.NET and C# compilers has this behaviour ... > If there's an implicit conversion from the literal 0 to enum ... Which there is.> if i try to use p0.Value in this case i have i logical bug ... i receive an Yes, you do. It's an unfortunate but rare consequence of the > unexpeted NullReferenceExpetion overloading rules, which make life better in the majority of cases. Of course, the same is true if you want to make a sql parameter where the actual *value* is a SqlDbType. Unlikely, but still problematic due to the constructor overloading. Fortunately, a simple cast to object will work in both cases. This isn't a bug - it's a design decision which you may not agree with, but everything's behaving as specified, I believe. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too
Other interesting topics
Interlocked vs Mutex efficiency
Finalization and .NET/deterministic or orderly shutdown Using AL.exe to link modules into assembly How to negotiate authenication with HttpWebRequest GUID for .Net framework Accessing information on IIS programatically on_Windows_98 Windows service configuration - registry or configuration file? Setting an application to auto size all it's controls based on resolution Listing people who are holding file locks |
|||||||||||||||||||||||