C# GetType与typeof

时间:2023-03-08 20:42:51

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

    public static void Main(string[] args)
{
A a = new B
{
a = "a",
b = "b",
c = "c",
};
B c = new B
{
a = "a",
b = "b",
c = "c",
};
put(a);
put<A>(c);
put<B>(c);
put<IC>(c);
Console.ReadLine();
}
public static void put<T>(T t)
{ Type type1 = typeof(T);
Console.WriteLine();
Console.WriteLine("****************typeof*******************************");
foreach (var item in type1.GetProperties())
{
string name = item.Name;
string value = item.GetValue(t).ToString();
Console.WriteLine("name=" + name + ",value=" + value);
}
Console.WriteLine("****************GetType*******************************");
Type type2 = t.GetType(); foreach (var item in type2.GetProperties())
{
string name = item.Name;
string value = item.GetValue(t).ToString();
Console.WriteLine("name=" + name + ",value=" + value);
} } public class A
{
public string a { get; set; }
}
public interface IC
{
string c { get; set; }
}
public class B : A,IC
{
public string c { get; set; }
public string b { get; set; }
}

在看看代码的执行结果:

C# GetType与typeof

  发现一个问题 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()有什么妙用的,我们来看下一段代码:

    public static void Main(string[] args)
{
D d = new D
{
a = "a",
b = ,
d1 = new D1 { d1 = },
time = DateTime.Now,
};
put2(d);
Console.ReadLine();
}
public static void put2<T>(T t)
{
Type type1 = typeof(T);
Console.WriteLine();
PropertyInfo[] Properties = type1.GetProperties(); foreach (PropertyInfo item in Properties)
{
Console.WriteLine(item.GetType().FullName);
string name = item.Name;
object value = item.GetValue(t); Console.WriteLine("参数的命名空间为:" +value.GetType().FullName);
Console.WriteLine("name=" + name + ",value=" + value.ToString());
}
}
public class D
{
public string a { get; set; }
public int b { get; set; }
public DateTime time { get; set; }
private string c { get; set; }
public D1 d1 { get; set; } }
public class D1
{
public int d1 { get; set; }
public override string ToString()
{
return d1.ToString();
}
}

这段代码输出为:

C# GetType与typeof

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

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

C# GetType与typeof

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