C# GetType与typeof

  在反射和泛型中经常会使用到Type类,获取Type的最常用的方法是 obj.GetType(),和typeof(T)。在获取泛型的type时有些小坑。

 1    public static void Main(string[] args)
 2         {
 3             A a = new B
 4             {
 5                 a = "a",
 6                 b = "b",
 7                 c = "c",
 8             };
 9             B c = new B
10             {
11                 a = "a",
12                 b = "b",
13                 c = "c",
14             };
15             put(a);
16             put<A>(c);
17             put<B>(c);
18             put<IC>(c);
19             Console.ReadLine();
20         }
21         public static void put<T>(T t)
22         {
23          
24             Type type1 = typeof(T);
25             Console.WriteLine();
26             Console.WriteLine("****************typeof*******************************");
27             foreach (var item in type1.GetProperties())
28             {
29                 string name = item.Name;
30                 string value = item.GetValue(t).ToString();
31                 Console.WriteLine("name=" + name + ",value=" + value);
32             }
33             Console.WriteLine("****************GetType*******************************");
34             Type type2 = t.GetType();
35 
36             foreach (var item in type2.GetProperties())
37             {
38                 string name = item.Name;
39                 string value = item.GetValue(t).ToString();
40                 Console.WriteLine("name=" + name + ",value=" + value);
41             }
42 
43         }
44 
45         public class A
46         {
47             public string a { get; set; }
48         }
49         public interface IC
50         {
51             string c { get; set; }
52         }
53         public class B : A,IC
54         {
55             public string c { get; set; }
56             public string b { get; set; }
57         }

在看看代码的执行结果:

  发现一个问题 GetType 和typeof的结果不一样。put<T>(T t)    显而易见,在传入相同的对象不同泛型  t.GetType()的返回值是确定的,而typeof(T)是可以变化的。obj.GetType()和定义obj的类型没有直接的关系,它的返回值是 YYYY obj = new XXXX() ; XXXX的类型,不一定是YYYY的类型。typeof就不用多说了

所以在此处代码应该写typeof(T),而不是t.GetType(),不然就失去泛型的意思。

GetType()有什么妙用的,我们来看下一段代码:

 1    public static void Main(string[] args)
 2         {
 3             D d = new D
 4             {
 5                 a = "a",
 6                 b = 1,
 7                 d1 = new D1 { d1 = 1 },
 8                 time = DateTime.Now,
 9             };
10             put2(d);
11             Console.ReadLine();
12         }
13         public static void put2<T>(T t)
14         {
15             Type type1 = typeof(T);
16             Console.WriteLine();
17             PropertyInfo[] Properties = type1.GetProperties();
18             
19             foreach (PropertyInfo item in Properties)
20             {
21                 Console.WriteLine(item.GetType().FullName);
22                 string name = item.Name;
23                 object value = item.GetValue(t);
24 
25                 Console.WriteLine("参数的命名空间为:" +value.GetType().FullName);
26                 Console.WriteLine("name=" + name + ",value=" + value.ToString());
27             }
28         }
29         public class D
30         {
31             public string a { get; set; }
32             public int b { get; set; }
33             public DateTime time { get; set; }
34             private string c  { get; set; }
35             public D1 d1 { get; set; }
36      
37         }
38         public class D1
39         {
40             public int d1 { get; set; }
41             public override string ToString()
42             {
43                 return d1.ToString();
44             }
45         }

这段代码输出为:

  这段代码的21行是输出item的命名空间,结果却是RuntimePropertyInfio不是定义的PropertyInfio。并且RuntimePropertyInfio这个类是不可以访问的。简单的推测出RuntimePropertyInfio 类的修饰词可能是private或者是internal,而且这个类是继承了PropertyInfio,同时也能推测出继承PropertyInfio的类绝对不是这一种。这个是c#源码中常用的一些手段。

  再来看item.getValue(t)中 在源码中的返回值是object,

而我们却而已通过GetType() 获得类具体的命名空间,通过这些方法就可以处理不用的参数。

 

posted @ 2017-01-02 14:50  灵行寻燕  阅读(13492)  评论(0编辑  收藏  举报