静态对象myValue = 0; static SqlTypeCode mySqlType = SqlTypeCode.Int32; static void Main(string [] args) { mySqlTyp e = SqlTypeCode.Int32; string sqlString = ToSqlString(); Console.WriteLine(" SqlString =" + sqlString); //传入0作为文字int mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString(0); Console.WriteLine(" SqlString =" + sqlString); //返回''true''而不是''0' mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString((int)0); Console.WriteLine(" SqlString =" + sqlString); //返回''true''而不是''0'' //传入0作为变量int myValue = 0; mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString(myValue); Console.WriteLine(" SqlString =" + sqlString); // 正确返回''0'' mySqlType = SqlTypeCode.DateTime; sqlString = ToSqlString(DateTime.Today); Console.WriteLine(" SqlString =" + sqlString); Console.ReadLine(); } 静态字符串ToSqlString() { 返回ToSqlString(myValue,mySqlType); } 静态字符串ToSqlString(object dataValue) { 返回ToSqlString(dataValue,mySqlType); } 静态字符串ToSqlString(SqlTypeCode sqlTypeCode) { 返回ToSqlString(myValue,sqlTypeCode); } 静态字符串ToSqlString(对象dataValue,SqlTypeCode sqlTypeCode) { switch(sqlTypeCode) { case SqlTypeCode.Boolean:return Convert.ToBoolean(dataValue).ToString(); case SqlTypeCode.Byte:return Convert.ToByte(dataValue).ToString(); case SqlTypeCode.Char:return"''" + Convert.ToChar(dataValue).ToString() +"''" ;; case SqlTypeCode.DateTime:return Convert .ToDateTime(dataValue).ToString(); case SqlTypeCode.Decimal:return Convert.ToDecimal(dataValue).ToString(); case SqlTypeCode.Int16:return Convert .ToInt16(dataValue).ToString(); case SqlTypeCode.Int32:return Convert.ToInt32(dataValue).ToString(); case SqlTypeCode.Int64:return Convert .ToInt64(dataValue).ToString(); case SqlTypeCode.Single:return Convert.ToSingle(dataValue).ToString(); case SqlTypeCode.String:return" ; '' " + Convert.ToString(dataValue).ToString()+"''" ;; case SqlTypeCode.TimeSpan:return TimeSpan .Parse(dataValue.ToString())。ToString(); } 返回" NULL"; } } } 解决方案 BTW ......我可以强迫通过提供 作为第三个单个参数覆盖来实现这种方式。 静态字符串ToSqlString(int dataValue) { 返回ToSqlString(dataValue,mySqlType); } 这间接强制对象覆盖在文字整数的情况下调用而不是 SqlTypeCode覆盖在枚举定义中具有有效值的 2007年5月17日星期四16:54:00 -0700,Gregg Walker< xy *** @newsgroup.nospam> 写道: [...] 看来每当使用符合有效枚举值的文字值转换为int时,c#将选择使用SqlTypeCode覆盖 而不是对象。现在,只要int类型的变量与 a值一起使用,可以转换为SqlTypeCode值,就会使用对象覆盖 (预期)。 给出了什么?这是一个错误还是我只是误解了什么? 我对C#来说太新了,无法解释为什么它会转换文字,但是盒子 变量。从表面上看,我同意这似乎是不一致的。 我敢打赌,虽然有一些合理的理由。 但是,在我看来,你真的不需要第三次重载 修复这个问题。如果你只是显式地转换参数(到对象), 那么这将确保你使用你期望的重载。我认为无论如何都要对重载方法进行模糊调用是个坏主意。即使编译规则是明确的,阅读代码的人也应该能够轻松地看到实际调用的是什么超载。 我也不清楚为什么不起作用的原因。 case返回true相反 的假,但我可能只是遗漏了你发布的代码中的内容。 Pete Gregg Walker< xy *** @ newsgroup.nospamwrote: 我正在测试一些代码,我有一个方法正在覆盖。 方法覆盖正常工作,直到我将 中的文字0(int值)作为唯一参数传递。 好吧,有两个可能的覆盖可以使用单个 参数调用。第一个采用一个对象,第二个采用枚举 类型(SqlTypeCode参见下面的代码)。由于文字0不是一个/ b SqlTypeCode我本来期望覆盖一个对象参数来运行 。然而,我发现是覆盖SqlTypeCode运行 而不是。 从0到任何枚举类型的隐式转换。 看来每当一个文字值,有资格作为有效枚举 值转换为int使用c#将选择使用SqlTypeCode覆盖 而不是对象。 嗯,根据C#规范,只有0才能在没有 警告的情况下进行转换。我相信Mono和MS编译器也会转换任何 hex文字进行转换。 我不确定为什么转换有一点都不这很有用 有时作为获得枚举值的简单方法,但我同意这是一个潜在的问题来源。 - Jon Skeet - < sk *** @ pobox.com> http://www.pobox.com/~skeet 博客: http://www.msmvps.com/jon.skeet 如果回复该群组,请不要给我发邮件 Hopefully someone can set me straight on this issue. I was testing some code where I have a method that is being overriden. Themethod overrides were working fine until I passed a literal 0 (int value) inas the lone argument. Well there are two possible overrides that could be called with a singleargument. The first one takes an object and the second one takes an enumtype (SqlTypeCode see the code below). Since a literal 0 is not aSqlTypeCode I would have expected the override taking an object argument tobe run. However what I found was the override taking the SqlTypeCode was runinstead. It appears that whenever a literal value that qualifies as a valid enumvalue cast to int is used c# will choose to use the SqlTypeCode overrideinstead of the object. Now whenever a variable of type int is used with avalue that can be cast to the SqlTypeCode value the object override(expected) is used. What gives? Is this a bug or am I just misunderstanding something? If this is not a bug it seems this issue could be something that hides inthe bushes for a long time until it jumps out and bites you. Thank you,--Gregg Walker Here''s the code from a console app... using System;using System.Collections.Generic;using System.Text; namespace EnumOverrideIssue{class Program{enum SqlTypeCode{Boolean,Byte,Char,DateTime,Decimal,Int16,Int32,Int64,Single,String,TimeSpan} static object myValue = 0;static SqlTypeCode mySqlType = SqlTypeCode.Int32; static void Main(string[] args){mySqlType = SqlTypeCode.Int32; string sqlString = ToSqlString();Console.WriteLine("SqlString=" + sqlString);// Pass in 0 as literal intmySqlType = SqlTypeCode.Int32; sqlString = ToSqlString(0);Console.WriteLine("SqlString=" + sqlString); // Returns ''true'' instead of ''0''mySqlType = SqlTypeCode.Int32; sqlString = ToSqlString((int)0);Console.WriteLine("SqlString=" + sqlString); // Returns ''true'' instead of ''0''// Pass in 0 as variable intmyValue = 0; mySqlType = SqlTypeCode.Int32; sqlString =ToSqlString(myValue); Console.WriteLine("SqlString=" + sqlString); //Correctly returns ''0''mySqlType = SqlTypeCode.DateTime; sqlString =ToSqlString(DateTime.Today); Console.WriteLine("SqlString=" + sqlString); Console.ReadLine();} static string ToSqlString(){return ToSqlString(myValue, mySqlType);} static string ToSqlString(object dataValue){return ToSqlString(dataValue, mySqlType);} static string ToSqlString(SqlTypeCode sqlTypeCode){return ToSqlString(myValue, sqlTypeCode);} static string ToSqlString(object dataValue, SqlTypeCode sqlTypeCode){switch(sqlTypeCode){case SqlTypeCode.Boolean: return Convert.ToBoolean(dataValue).ToString();case SqlTypeCode.Byte: return Convert.ToByte(dataValue).ToString();case SqlTypeCode.Char: return "''" + Convert.ToChar(dataValue).ToString()+ "''";case SqlTypeCode.DateTime: returnConvert.ToDateTime(dataValue).ToString();case SqlTypeCode.Decimal: return Convert.ToDecimal(dataValue).ToString();case SqlTypeCode.Int16: return Convert.ToInt16(dataValue).ToString();case SqlTypeCode.Int32: return Convert.ToInt32(dataValue).ToString();case SqlTypeCode.Int64: return Convert.ToInt64(dataValue).ToString();case SqlTypeCode.Single: return Convert.ToSingle(dataValue).ToString();case SqlTypeCode.String: return "''" +Convert.ToString(dataValue).ToString() + "''";case SqlTypeCode.TimeSpan: returnTimeSpan.Parse(dataValue.ToString()).ToString();} return "NULL";}}} 解决方案 BTW... I can force this to work the way I''m expecting by providing thefollowing as a third single argument override. static string ToSqlString(int dataValue){return ToSqlString(dataValue, mySqlType);} This indirectly forces the object override to be called instead of theSqlTypeCode override in the case of literal ints that have a valid value inthe enum definition.On Thu, 17 May 2007 16:54:00 -0700, Gregg Walker <xy***@newsgroup.nospam>wrote: [...]It appears that whenever a literal value that qualifies as a valid enumvalue cast to int is used c# will choose to use the SqlTypeCode overrideinstead of the object. Now whenever a variable of type int is used witha value that can be cast to the SqlTypeCode value the object override(expected) is used.What gives? Is this a bug or am I just misunderstanding something?I''m too new to C# to be able to explain why it casts literals, but boxesvariables. On the face of it, I agree that appears to be inconsistent.I''ll bet there''s some reasonably good reason though. However, it does seem to me that you don''t really need a third overload tofix the issue. If you''d just cast the parameter explicitly (to "object"),then that would ensure that you use the overload you expect. I think it''sa bad idea to have ambiguous calls to overloaded methods anyway. Even ifthe compiler rules are explicit, people reading the code should be able toeasily see what overload actually gets called. I''m also not clear on why the "doesn''t work" case returns "true" insteadof "false", but I''m probably just missing something in the code you posted. PeteGregg Walker <xy***@newsgroup.nospamwrote:I was testing some code where I have a method that is being overriden. Themethod overrides were working fine until I passed a literal 0 (int value) inas the lone argument.Well there are two possible overrides that could be called with a singleargument. The first one takes an object and the second one takes an enumtype (SqlTypeCode see the code below). Since a literal 0 is not aSqlTypeCode I would have expected the override taking an object argument tobe run. However what I found was the override taking the SqlTypeCode was runinstead.There''s an implicit conversion from 0 to any enum type. It appears that whenever a literal value that qualifies as a valid enumvalue cast to int is used c# will choose to use the SqlTypeCode overrideinstead of the object.Well, according to the C# spec, only 0 should be converted withoutwarning. I believe that both the Mono and MS compilers also convert anyhex literal to be converted. I''m not exactly sure why the conversion is there at all. It''s usefulsometimes as an easy way of getting an enum value, but I agree it''s apotential source of problems. --Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeetIf replying to the group, please do not mail me too 这篇关于这个代码有什么不对(也许是一个错误!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-19 06:38