C# 如何将字符串转换为在运行时确定的可空类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9428333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 07:22:53  来源:igfitidea点击:

How to Convert a String to a Nullable Type Which is Determined at Runtime?

c#asp.netgenericsdatetimenullable

提问by The Light

I have the below code and I'd need to convert a string to a type which is also specified from String:

我有以下代码,我需要将字符串转换为也从字符串指定的类型:

 Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");

            object d = Convert.ChangeType("2012-02-23 10:00:00", t);

I get the below error messagE:

我收到以下错误消息:

Invalid cast from 'System.String' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

How would that be nicely possible?

那怎么可能呢?

I know one ugly way would be to check whether the type is nullable using if:

我知道一种丑陋的方法是使用 if 检查类型是否可为空:

    Type possiblyNullableType = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");

    var underlyingType = Nullable.GetUnderlyingType(possiblyNullableType);

    Object result;

    // if it's null, it means it wasn't nullable
    if (underlyingType != null)
    {
        result = Convert.ChangeType("2012-02-23 10:00:00", underlyingType);
    }

Would there be any better way?

会不会有更好的办法?

Thanks,

谢谢,

采纳答案by Paddy

There are two problems.

有两个问题。

Firstly, Convert.ChangeTypejust plain does not support nullable types.

首先,Convert.ChangeType只是普通不支持可为空类型。

Secondly, even if it did, by boxing the result (assigning it to an object), you'd already be converting it to a DateTime.

其次,即使是这样,通过装箱结果(将其分配给 an object),您已经将其转换为 a DateTime

You could special case nullable types:

您可以特殊情况下可为空类型:

string s = "2012-02-23 10:00:00";
Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");
object d;

if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    if (String.IsNullOrEmpty(s))
        d = null;
    else
        d = Convert.ChangeType(s, t.GetGenericArguments()[0]);
}
else
{
    d = Convert.ChangeType(s, t);
}

回答by Paddy

Something like this? Unless you really need to do it dynamically.

像这样的东西?除非你真的需要动态地做。

if (string.IsNullOrEmpty(input))
{
   return new DateTime?();
}
else
{
   return new DateTime?(DateTime.Parse(input));
}


Possibly you could check to see if your type is one of the 'nullable' types and then maybe you could find something useful here:

也许您可以检查您的类型是否是“可为空”类型之一,然后也许您可以在这里找到一些有用的东西:

Convert string to nullable type (int, double, etc...)

将字符串转换为可空类型(int、double 等...)

回答by The Light

I wrote the below generic helper method which works in most scenarios (not tested with generic types):

我编写了以下通用辅助方法,该方法适用于大多数场景(未使用泛型类型进行测试):

static void Main(string[] args)
{
    Object result =
        ConvertValue(
            "System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]",
            "2012-02-23 10:00:00");
}

public static Object ConvertValue(string typeInString, string value)
{
    Type originalType = Type.GetType(typeInString);

    var underlyingType = Nullable.GetUnderlyingType(originalType);

    // if underlyingType has null value, it means the original type wasn't nullable
    object instance = Convert.ChangeType(value, underlyingType ?? originalType);

    return instance;
}

回答by Hossein Shahabi

public static T GetValue<T>(string Literal, T DefaultValue)
    {
        if (Literal == null || Literal == "" || Literal == string.Empty) return DefaultValue;
        IConvertible obj = Literal;
        Type t = typeof(T);
        Type u = Nullable.GetUnderlyingType(t);

        if (u != null)
        {
            return (obj == null) ? DefaultValue : (T)Convert.ChangeType(obj, u);
        }
        else
        {
            return (T)Convert.ChangeType(obj, t);
        }
    }