【问题标题】:In C#, when does Type.FullName return null?在 C# 中,Type.FullName 什么时候返回 null?
【发布时间】:2016-01-08 06:37:39
【问题描述】:

MSDN for Type.FullName 表示该属性返回

null 如果当前实例表示泛型类型参数、数组类型、指针类型或基于类型参数的 byref 类型,或者是不是泛型类型定义,但包含未解析的类型参数。

我数了五个案例,我发现每一个都比上一个更不清楚。这是我尝试构建每个案例的示例。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication {
  public static class Program {

    public static void Main(string[] args) {
      GenericTypeParameter();
      ArrayType();
      PointerType();
      ByRefTypeBasedOnTypeParameter();
      NongenericTypeDefinitionWithUnresolvedTypeParameters();
      Console.ReadKey();
    }

    public static void GenericTypeParameter() {
      var type = typeof(IEnumerable<>)
        .GetGenericArguments()
        .First();
      PrintFullName("Generic type parameter", type);
    }

    public static void ArrayType() {
      var type = typeof(object[]);
      PrintFullName("Array type", type);
    }

    public static void PointerType() {
      var type = typeof(int*);
      PrintFullName("Pointer type", type);
    }

    public static void ByRefTypeBasedOnTypeParameter() {
      var type = null;
      PrintFullName("ByRef type based on type parameter", type);
    }

    private static void NongenericTypeDefinitionWithUnresolvedTypeParameters() {
      var type = null;
      PrintFullName("Nongeneric type definition with unresolved type parameters", type);
    }

    public static void PrintFullName(string name, Type type) {
      Console.WriteLine(name + ":");
      Console.WriteLine("--Name: " + type.Name);
      Console.WriteLine("--FullName: " + (type.FullName ?? "null"));
      Console.WriteLine();
    }
  }
}

哪个有这个输出。

Generic type parameter:
--Name: T
--FullName: null

Array type:
--Name: Object[]
--FullName: System.Object[]

Pointer type:
--Name: Int32*
--FullName: System.Int32*

ByRef type based on type parameter:
--Name: Program
--FullName: ConsoleApplication.Program

Nongeneric type definition with unresolved type parameters:
--Name: Program
--FullName: ConsoleApplication.Program

我只有五分之一,有两个“空白”。

问题

有人可以修改我的代码以给出 Type.FullName 可以为空的每种方式的简单示例吗?

【问题讨论】:

    标签: c# arrays pointers generics types


    【解决方案1】:

    所以我立即注意到 MSDN 引用的案例列表中包含两次“或”,但我花了很长时间才意识到原因。现实情况是,存在三个主要案例,其中三个案例中的一个被拆分为另外三个案例。使用更清晰的标点符号,案例是

    1. 泛型类型参数;
    2. 数组类型、指针类型或基于类型参数的byref类型;或
    3. 不是泛型类型定义但包含未解析类型参数的泛型类型。

    我理解第一个案例,Rahul 的回答将我引导至this MSDN blog post,它解释并给出了最后一个案例的两个示例,现在我可以举出其余案例的示例。

    using System;
    using System.Linq;
    
    namespace ConsoleApplication {
    
      public class GenericClass<T> {
        public void ArrayMethod(T[] parameter) { }
        public void ReferenceMethod(ref T parameter) { }
      }
    
      public class AnotherGenericClass<T> : GenericClass<T> { }
    
      public static class Program {
    
        public static void Main(string[] args) {
          GenericTypeParameter();
          ArrayTypeBasedOnTypeParameter();
          PointerTypeBasedOnTypeParameter();
          ByRefTypeBasedOnTypeParameter();
          NongenericTypeDefinitionWithUnresolvedTypeParameters();
          Console.ReadKey();
        }
    
        public static void GenericTypeParameter() {
          var type = typeof(GenericClass<>)
            .GetGenericArguments()
            .First();
          PrintFullName("Generic type parameter", type);
        }
    
        public static void ArrayTypeBasedOnTypeParameter() {
          var type = typeof(GenericClass<>)
            .GetMethod("ArrayMethod")
            .GetParameters()
            .First()
            .ParameterType;
          PrintFullName("Array type based on type parameter", type);
        }
    
        /*
         * Would like an actual example of a pointer to a generic type,
         * but this works for now.
         */
        public static void PointerTypeBasedOnTypeParameter() {
          var type = typeof(GenericClass<>)
            .GetGenericArguments()
            .First()
            .MakePointerType();
          PrintFullName("Pointer type based on type parameter", type);
        }
    
        public static void ByRefTypeBasedOnTypeParameter() {
          var type = typeof(GenericClass<>)
            .GetMethod("ReferenceMethod")
            .GetParameters()
            .First()
            .ParameterType;
          PrintFullName("ByRef type based on type parameter", type);
        }
    
        private static void NongenericTypeDefinitionWithUnresolvedTypeParameters() {
          var type = typeof(AnotherGenericClass<>).BaseType;
          PrintFullName("Nongeneric type definition with unresolved type parameters", type);
        }
    
        public static void PrintFullName(string name, Type type) {
          Console.WriteLine(name + ":");
          Console.WriteLine("--Name: " + type.Name);
          Console.WriteLine("--FullName: " + (type.FullName ?? "null"));
          Console.WriteLine();
        }
      }
    }
    
    /***Output***
    Generic type parameter:
    --Name: T
    --FullName: null
    
    Array type based on type parameter:
    --Name: T[]
    --FullName: null
    
    Pointer type based on type parameter:
    --Name: T*
    --FullName: null
    
    Byref type based on type parameter:
    --Name: T&
    --FullName: null
    
    Nongeneric type definition with unresolved type parameters:
    --Name: GenericClass`1
    --FullName: null
    ***Output***/
    

    【讨论】:

      【解决方案2】:

      您可以查看MSDN blog,它演示了Type.FullName 何时返回null

      例如,假设我们有一个使用以下内容编译的程序集 C#代码:

      class G<T> {
          public void M<S>() { } 
      }
      

      typeof(G&lt;&gt;).FullNameG`1,我们可以从 类型.GetType(G`1)。但是我们可以构建更复杂的泛型类型, 比如G&lt;S&gt;(类型G&lt;&gt;绑定了泛型参数 方法M&lt;&gt;);为了用字符串识别这种类型,很多 需要额外的信息。

      以下是 Type.FullName 返回 null 的一些示例。

      class G<T> {
        public class C { }
        public void M(C arg) { }
      }
      class G2<T> : G<T> { }
      
      string s1 = typeof(G<>).GetGenericArguments()[0].FullName; 
      // T in G<T>: generic parameter
      string s2 = typeof(G<>).GetMethod("M").GetParameters()[0].ParameterType.FullName; 
      // check out the IL, it is G`1/C<!T> (not generic type definition) 
      // Related topic, see this 
      string s3 = typeof(G2<>).BaseType.FullName; 
      // base type of G2<>, which is not generic type definition either
      // it equals to typeof(G<>).MakeGenericType(typeof(G2<>).GetGenericArguments()[0])
      

      【讨论】:

      • 太棒了。这篇博文是关于五个案例中的最后一个(参见他的最后两个示例),但还包括第一个案例的示例(参见他的第一个示例)以进行比较。还有三个案例。
      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      • 1970-01-01
      • 2012-06-03
      • 2015-02-10
      • 1970-01-01
      相关资源
      最近更新 更多