反射类型的默认值(T)
在浏览其他答案时,我想出了以下扩展方法,它很有效:
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 );
}
我可以像这样使用它:
string s = "2011-09-21 17:45";
DateTime result = s.ConvertTo( typeof( DateTime ) );
if ( result == DateTime.MinValue )
doSomethingWithTheBadData();
太棒了!效果很好。现在,我想对反射类型做类似的事情。我有:
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() 位进行了硬编码。在我的应用程序中,类型都得到了反映。
感谢大家的快速答复!
In browsing other answers, I have come up with the following extension method which works a treat:
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 );
}
And I can use it like:
string s = "2011-09-21 17:45";
DateTime result = s.ConvertTo( typeof( DateTime ) );
if ( result == DateTime.MinValue )
doSomethingWithTheBadData();
Awesome! Works great. Now, I'd like to do something similar with a reflected type. I have:
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
}
And I'd like to use it thus:
Type someType; // will be DateTime, int, etc., but not known until runtime
DateTime result = s.ConvertTo( sometype );
if ( result == DateTime.MinValue )
doSomethingWithTheBadData();
Of course, the compiler objects to the 'bogus' lines in the ConvertTo method. What I need (ok, don't necessarily need, but it'd be nice) is a way to get the same result as in the first example so that if the conversion fails, something that can be assigned to the reflected object is returned and can be recognized in the same manner as in the first example.
Edit:
What I finished with:
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;
}
and used:
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();
Remembering that, for the purpose of demonstration, I'm hard-coding the typeof() bit. In my application, the types are all reflected.
Thanks to all for the speedy answers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
This,因为值类型保证有一个默认构造函数,而引用类型的默认值为
null
。You can use
This is because value types are guaranteed to have a default constructor, and the default value of a reference type is a
null
.如果您使用
typeof(Type)
传递类型,那么显然您可以只使用第一种方法。那么,假设您通过反射获取类型(您说的是),那么您还可以使用反射来获取第一个版本的Convert()
MethodInfo code>,然后使用MakeGenericMethod()
将您的反射类型替换为它:If you're passing in the type using
typeof(Type)
, then obviously you could just use the first method. Assuming, then, that you're getting the type via reflection (which you say you are) then you can also use reflection to get theMethodInfo
for your first version ofConvert()
, and then useMakeGenericMethod()
to substitute your reflected type into it:未经测试,但也许是这样的?
Untested, but maybe something like this?