从作为字符串传递的值中获取数据类型返回值。简单的有SQL、Access和Oracle。更难的是Sharepoint,CSV。如果我从基于文本的源返回一个值,我想确定数据的数据类型。由于CSV是全文,因此没有要查询的元数据,我需要以某种方式解析数据以确定数据类型。示例:“true”、“true”、“false”、“false”的列表将是一个布尔值列表“1”、“0”、“1”、“0”将是一个布尔值列表值“1”、“4”、“-10”、“500”将是一个整数列表“15.2”、“2015.5896”、“1.0245”、“500”将是一个双精度列表“2001/01”/01","2010/05/2912:00","1989/12/2510:34:21"是基于https://stackoverflow.com/questions/606365/c-doubt-的日期时间列表查找数据类型/606381#606381objectParseString(stringstr){Int32intValue;Int64bigintValue;双双值;布尔布尔值;日期时间日期值;//将检查放在if-else语句的较高位置,以赋予类型更高的优先级。如果(Int32.TryParse(str,outintValue))返回intValue;elseif(Int64.TryParse(str,outbigintValue))返回bigintValue;elseif(double.TryParse(str,outdoubleValue))returndoubleValue;elseif(bool.TryParse(str,outboolValue))returnboolValue;elseif(DateTime.TryParse(str,outdateValue))返回dateValue;否则返回海峡;}编辑:我只需要以下内容:BITDATETIMEINTNVARCHAR(255)NVARCHAR(MAX)BIGINTDECIMAL(36,17)你能看到优先级的任何改进吗?我想出了以下有效的解决方案:enumdataType{System_Boolean=0,System_Int32=1,System_Int64=2,System_Double=3,System_DateTime=4,System_String=5}privatedataTypeParseString(stringstr){boolboolValue;Int32整数值;Int64bigintValue;双双值;日期时间日期值;//将检查放在if-else语句的较高位置,以赋予类型更高的优先级。如果(bool.TryParse(str,outboolValue))返回dataType.System_Boolean;elseif(Int32.TryParse(str,outintValue))returndataType.System_Int32;elseif(Int64.TryParse(str,outbigintValue))返回dataType.System_Int64;elseif(double.TryParse(str,outdoubleValue))returndataType.System_Double;elseif(DateTime.TryParse(str,outdateValue))返回dataType.System_DateTime;否则返回dataType.System_String;}//////获取Datacolumn列的数据类型//////Datacolumn获取///DataTable的数据类型///refvalue返回字符串类型的大小///publicTypeGetColumnType(DataColumncolumn,DataTabledt,refintcolSize){TypeT;DataViewdv=newDataView(dt);//获取最小值和最大值stringcolName=column.ColumnName;dv.RowFilter="["+colName+"]=MIN(["+colName+"])";数据表dtRange=dv.ToTable();字符串strMinValue=dtRange.Rows[0][column.ColumnName].ToString();intminValueLevel=(int)ParseString(strMinValue);dv.RowFilter="["+colName+"]=MAX(["+colName+"])";dtRange=dv.ToTable();字符串strMaxValue=dtRange.Rows[0][列。列名].ToString();intmaxValueLevel=(int)ParseString(strMaxValue);colSize=strMaxValue.Length;//获取前n到50行的最大类型级别intsampleSize=Math.Max(dt.Rows.Count,50);intmaxLevel=Math.Max(minValueLevel,maxValueLevel);for(inti=0;i由于Dimi提供了赏金并需要一个更“现代”的解决方案,我将尝试提供第一个,我们需要从一个合理的类开始将字符串转换为不同的东西?基本行为的合理行为类型。尊重文化信息,尤其是在转换数字和日期时。如果需要,可以使用自定义转换器扩展逻辑。作为奖励,避免长“if”链,因为它们很容易出错。publicclassStringConverter{//委托TryParse(string,outT)publicdelegateboolTypedConvertDelegate(stringvalue,outTresult);//TryParse(string,outobject)委托privatedelegateboolUntypedConvertDelegate(stringvalue,outobjectresult);privatereadonlyList_converters=newList();//默认转换器,延迟初始化privatestaticreadonlyLazy_default=newLazy(CreateDefault,true);publicstaticStringConverterDefault=>_default.Value;privatestaticStringConverterCreateDefault(){vard=newStringConverter();//为常见的.NET类型添加合理的默认转换器。不要忘记考虑文化,这在解析数字/日期时很重要。d.AddConverter(bool.TryParse);d.AddConverter((stringvalue,outbyteresult)=>byte.TryParse(value,NumberStyles.Integer,d.Culture,outresult));d.AddConverter((stringvalue,outshortresult)=>short.TryParse(value,NumberStyles.Integer,d.Culture,outresult));d.AddConverter((stringvalue,outintresult)=>int.TryParse(value,NumberStyles.Integer,d.Culture,outresult));d.AddConverter((stringvalue,outlongresult)=>long.TryParse(value,NumberStyles.Integer,d.Culture,outresult));d.AddConverter((stringvalue,outfloatresult)=>float.TryParse(value,NumberStyles.Number,d.Culture,outresult));d.AddConverter((stringvalue,outdoubleresult)=>double.TryParse(value,NumberStyles.Number,d.Culture,outresult));d.AddConverter((stringvalue,outDateTimeresult)=>DateTime.TryParse(value,d.Culture,DateTimeStyles.None,outresult));返回d;}//publicCultureInfo文化{get;放;}=CultureInfo.CurrentCulture;publicvoidAddConverter(Predicatematch,Funcconverter){//从匹配谓词创建转换器并转换函数_converters.Add((stringvalue,outobjectresult)=>{if(match(value)){result=converter(value);返回真值;}结果=null;返回假;});}publicvoidAddConverter(Regexmatch,Funcconverter){//从匹配正则表达式创建转换器并转换函数_converters.Add((stringvalue,outobjectresult)=>{if(match.IsMatch(value)){result=converter(值);返回真;}结果=空;返回假;});}publicvoidAddConverter(TypedConvertDelegateconstructor){//从类型化的TryParse(string,outT)函数创建转换器_converters.Add(FromTryPattern(constructor));}publicboolTryConvert(stringvalue,outobjectresult){if(this!=Default){//如果这不是默认转换器-首先尝试使用默认转换if(Default.TryConvert(value,outresult))returntrue;}//然后使用本地转换器。Any将在第一个匹配对象tmp=null之后返回;boolanyMatch=_converters.Any(c=>c(value,outtmp));结果=tmp;返回任何匹配项;}privatestaticUntypedConvertDelegateFromTryPattern(TypedConvertDelegateinner){return(stringvalue,输出对象结果)=>{Ttmp;if(inner.Invoke(value,outtmp)){结果=tmp;返回真;}else{结果=null;返回假;}};}}使用这样:staticvoidMain(string[]args){//将文化设置为不变StringConverter.Default.Culture=CultureInfo.InvariantCulture;//将自定义转换器添加到默认值,它将匹配以CUSTOM:开头的字符串并返回MyCustomClassStringConverter.Default.AddConverter(c=>c.StartsWith("CUSTOM:"),c=>newMyCustomClass(c));varitems=new[]{"1","4343434343","3.33","true","false","2014-10-1022:00:00","CUSTOM:something"};foreach(variteminitems){对象结果;如果(StringConverter.Default.TryConvert(item,outresult)){Console.WriteLine(result);}}//创建新的非默认转换器varlocalConverter=newStringConverter();//添加自定义转换器以解析与MySecondCustomClass模式匹配的jsonlocalConverter.AddConverter((stringvalue,outMySecondCustomClassresult)=>TryParseJson(value,@"{'value':{'type':'string'}}",outresult));{对象结果;//检查是否可行}}Console.ReadKey();}staticboolTryParseJson(stringjson,stringrawSchema,outTresult)whereT:new(){//我们在这里使用Newtonsoft.JsonvarparsedSchema=JsonSchema.Parse(rawSchema);JObjectjObject=JObject.Parse(json);如果(jObject.IsValid(parsedSchema)){结果=JsonConvert.DeserializeObject(json);返回真;}else{result=default(T);返回假;}}classMyCustomClass{publicMyCustomClass(stringvalue){this.Value=value;}公共字符串值{得到;私有集;}}publicclassMySecondCustomClass{publicstringValue{get;放;}}列表类型=newList(newType[]{typeof(Boolean),typeof(int),typeof(double),typeof(DateTime)});字符串t=“真”;对象返回;foreach(在类型中输入类型){TypeConvertertc=TypeDescriptor.GetConverter(type);if(tc!=null){try{objectobj=tc.ConvertFromString(t);//你的返回值;}catch(Exception){continue;}}}使用.ToInt16()、.ToInt32()、.ToBool()等将其存储在通用数据类型中不是更容易吗?如果您编写的应用程序需要一个int并且它得到一个boolean它将失败,所以最好让程序员明确地转换为预期的数据类型您的方法的问题是您不知道包含0的行因为第一项是Include-100000asitemnumber100。这意味着在对所有不同数据类型的所有行都进行TryParsed之前,您无法成功转换。运营成本非常高!如果可用,我会使用预编译的正则表达式和/或自定义逻辑来处理数据。例如,遍历所有行以查找最高/最低数字、字符串的出现次数等。从最窄的类型开始并逐渐增加到最宽的类型可能不是最好的方法。如果我对数据一无所知,我会从最常见的类型开始,然后朝着最少的方向努力。如果不知道,我可能会或可能不会做一些研究来了解可能的统计数据(如果可能的话)。另外,我只是在做我最好的猜测。如果您只希望每10,000条记录发生一次,为什么要提前测试位或日期时间?以上就是C#学习教程:从字符串传递的值中获取数据类型共享的所有内容。如果对你有用,需要了解更多C#学习教程,希望大家多多关注---本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处:
