【问题标题】:Get a nullable type from a type name从类型名称中获取可为空的类型
【发布时间】:2018-02-14 03:59:15
【问题描述】:

我有以下情况,我得到一个如下所示的字符串

"System.DateTime?"

"int?"

我希望能够做的是检索该字符串的 System.Type,如下所示:

{Name = "Nullable1" FullName = "System.Nullable1[[System.DateTime, mscorlib,版本=4.0.0.0,文化=中性, PublicKeyToken=b77a5c561934e089]]"}

现在我知道如何从字符串中检索类型了,我可以在处理不可为空的类型时说 Type.GetType("System.DateTime"),或者在我知道 DateTime 可以为空时说 typeof(DateTime?),但在这种情况下,我不知道what 可以为空的类型可能会通过并且只会将其作为字符串接收。

【问题讨论】:

  • 我猜应该是Nullable<T>
  • 是什么生成了该字符串,为什么它没有为该类型生成正确的名称?
  • @gunr2171 他们有一个字符串,而不是Type,因此该帖子并没有真正的帮助。他们也不需要底层类型,他们需要 Nullable Type 值。
  • 您是否需要支持 any 字符串,这些字符串可能会在 .NET 中命名为合法类型,或者您需要支持的内容有限?我问是因为......你需要支持 this 字符串吗? "Namespace1.Namespace2.Generic<int, string>.Nested.Inner<DateTime>.NestedInner<int?>" ?

标签: c# types nullable


【解决方案1】:

我遗漏了部分上下文 - 例如,字符串是否总是表示可以为空的值类型?

鉴于您可以从字符串中提取值类型名称并创建对该类型的引用:

var valueType = Type.GetType("System.DateTime");
var nullableType = typeof(Nullable<>).MakeGenericType(valueType);

这应该可以解决部分问题。更难的部分是从字符串中确定基础类型,这取决于您收到的输入类型。从System.DateTime 获取类型很容易,但从int 获取类型更难。 This answer 可能会对这部分有所帮助。


就输入而言 - 是否有任何选项可以向用户提供可用选项列表,以便您收到的输入始终是有效的类型名称?那将否定对任何这些的需求。然后你可以做Type.GetType(stringWithTypeName)

【讨论】:

    【解决方案2】:

    除了 Scott 的回答,您还可以使用正确名称的 Type.GetType

    System.Nullable`1[System.DateTime]
    

    所以这个函数会为你返回正确的类型。

    public Type GetType(string typeString)
    {
        if (typeString.EndsWith("?"))
        {
            typeString = $"System.Nullable`1[{typeString.TrimEnd('?')}]";
        }
        return Type.GetType(typeString);
    }
    

    【讨论】:

    • 或者只是typeString.TrimEnd('?')。我原本打算包括这部分,但我对输入有点困惑。如果它是可靠的类型名称,则它可以工作,但如果它是 int 之类的别名或缺少命名空间,则不能。我确信有办法解决它,但意图似乎不清楚。
    • 是的...TrimEnd 听起来更好。我忘了。谢谢。关于别名,就像你说的那样,它不起作用,并且 jon skeet 提供了一个很好的“复制/粘贴”字典(在你提供的链接中),OP 可以使用。
    【解决方案3】:

    解决这个问题的一种方法是为“Type”类型创建一个扩展方法,并实现该方法以检查它是否为可空类型并返回正确的类型。如下示例:

    namespace ExtensionMethod  
        {
            public static class MyExtensions
            {
                public static Type GetNullabeType(this Type t, string typeName)
                {
                    string typeString = typeName;
                    var typeNonNullabe = Type.GetType(typeString.Replace("?", ""));
                    if (typeString.Contains("?") && typeNonNullabe != null)
                    {
                        return typeof(Nullable<>).MakeGenericType(typeNonNullabe);
                    }
                    return t;
                }
            }
        }
    

    之后,只需使用这个扩展方法如下:

    Type t = null;
    var type = t.GetNullabeType("System.DateTime?");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-04
      • 2017-04-25
      • 2019-01-18
      • 1970-01-01
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      相关资源
      最近更新 更多