C# 反射类型的默认值(T)
在浏览其他答案的过程中,我提出了以下扩展方法:C# 反射类型的默认值(T),c#,generics,reflection,C#,Generics,Reflection,在浏览其他答案的过程中,我提出了以下扩展方法: public static T Convert<T>( this string input ) { var converter = TypeDescriptor.GetConverter( typeof( T ) ); if ( converter != null ) { try { T result = (T) converter.ConvertFromS
public static T Convert<T>( this string input )
{
var converter = TypeDescriptor.GetConverter( typeof( T ) );
if ( converter != null )
{
try
{
T result = (T) converter.ConvertFromString( input );
return result;
}
catch
{
return default( T );
}
}
return default( T );
}
太棒了!效果很好。现在,我想用反射类型做一些类似的事情。我有:
public static dynamic ConvertTo( this string input, Type type )
{
var converter = TypeDescriptor.GetConverter( type );
if ( converter != null )
{
try
{
dynamic result = converter.ConvertFromString( input );
return ( result );
}
catch
{
return default( type ); // bogus
}
}
return default( type ); // bogus
}
我想这样使用它:
Type someType; // will be DateTime, int, etc., but not known until runtime
DateTime result = s.ConvertTo( sometype );
if ( result == DateTime.MinValue )
doSomethingWithTheBadData();
当然,编译器反对ConvertTo方法中的“伪”行。我需要的(好的,不一定需要,但最好是这样)是一种获得与第一个示例中相同结果的方法,这样,如果转换失败,可以指定给反射对象的内容将返回,并且可以以与第一个示例中相同的方式识别
编辑:
我完成的是:
public static dynamic ConvertTo( this string input, Type type, out bool success )
{
dynamic result;
var converter = TypeDescriptor.GetConverter( type );
if ( converter != null )
{
try
{
result = converter.ConvertFromString( input );
success = true;
return result;
}
catch { /* swallow the exception */ }
}
result = type.IsValueType ? Activator.CreateInstance( type ) : null;
success = false;
return result;
}
并使用:
bool success;
string val = "2011-09-21 17:25";
dateTime = val.ConvertTo( typeof( DateTime ), out success );
if ( success )
doSomethingGood();
val = "foo";
dateTime = val.ConvertTo( typeof( DateTime ), out success );
if ( !success )
dealWithBadData();
记住,为了演示,我正在硬编码typeof()位。在我的应用程序中,所有类型都会反映出来
感谢大家的快速回答 如果您使用
typeof(type)
传递类型,那么显然您可以使用第一种方法。那么,假设您是通过反射获得类型的(您说您是这样),那么您也可以使用反射为第一个版本的Convert()
获取MethodInfo
,然后使用MakeGenericMethod()
将反射的类型替换为它:
MethodInfo m = typeof(MyConvertExtensions).GetMethod("Convert");
MethodInfo invocable = m.MakeGenericMethod(myReflectedType);
invocable.Invoke(null, new[] { myString });
你可以用
//to get default(T) from an instance of Type
type.IsValueType ? Activator.CreateInstance(type) : null;
这是因为值类型保证有一个默认构造函数,而引用类型的默认值是未测试的
null
,但可能是这样的
public static dynamic ConvertTo(this string input, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null)
{
try
{
return converter.ConvertFromString(input);
}
catch
{
// ignore
}
}
if (type.IsValueType)
return Activator.CreateInstance(type);
return null;
}
我只是把这个打出来。太好了,正是我需要的。谢谢(我已经编辑了原始问题,以包含我的“最终”代码。)
public static dynamic ConvertTo(this string input, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null)
{
try
{
return converter.ConvertFromString(input);
}
catch
{
// ignore
}
}
if (type.IsValueType)
return Activator.CreateInstance(type);
return null;
}