111,129
社区成员
发帖
与我相关
我的任务
分享<STRONG><FONT style="FONT-SIZE: 20px" size=5>■ dynamic类型</FONT><BR></STRONG> C#从1.0版开始,就可以即使不知道一个对象的类型,在编译时也可以动态访问这个对象的信息。只要使用反射就可以了。<BR><BR>
<DIV style="BORDER-RIGHT: #600 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #600 0px solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; BACKGROUND: #fdd no-repeat left top; PADDING-BOTTOM: 10px; BORDER-LEFT: #600 0px solid; WIDTH: 99%; COLOR: darkred; PADDING-TOP: 10px; BORDER-BOTTOM: #600 0px solid"><FONT style="FONT-SIZE: 16px"><FONT style="FONT-SIZE: 14px">使用反射访问对象的成员信息<BR></FONT></FONT>
<TABLE style="TABLE-LAYOUT: fixed; FONT-WEIGHT: normal; WIDTH: 100%; FONT-FAMILY: ">
<TBODY>
<TR>
<TD><PRE style="BORDER-RIGHT: red 2px dotted; PADDING-RIGHT: 10px; BORDER-TOP: red 2px dotted; PADDING-LEFT: 10px; FONT-SIZE: 9pt; PADDING-BOTTOM: 5px; MARGIN: 1px; BORDER-LEFT: red 2px dotted; WIDTH: 99%; COLOR: brown; LINE-HEIGHT: 1.4em; PADDING-TOP: 10px; BORDER-BOTTOM: red 2px dotted; BACKGROUND-COLOR: #fff">
<BR>
class A<BR>
{<BR>
public readonly string MyName = "陆凌牛";<BR>
public static object GetObjectA() { return new A(); }<BR>
}<BR>
class Program<BR>
{<BR>
static void Main(string[] args)<BR>
{<BR>
object a = A.GetObjectA();<BR>
var name = a.GetType().GetField("MyName").GetValue(a);<BR>
Console.WriteLine(name);<BR>
}<BR>
}
</PRE></TD></TR></TBODY></TABLE></DIV><BR>
<DIV style="BORDER-RIGHT: #600 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #600 0px solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; BACKGROUND: #dfd no-repeat left top; PADDING-BOTTOM: 10px; BORDER-LEFT: #600 0px solid; WIDTH: 99%; COLOR: darkred; PADDING-TOP: 10px; BORDER-BOTTOM: #600 0px solid">上例的执行结果
<TABLE style="TABLE-LAYOUT: fixed; FONT-WEIGHT: normal; WIDTH: 100%; FONT-FAMILY: ">
<TBODY>
<TR>
<TD><PRE style="BORDER-RIGHT: red 2px dotted; PADDING-RIGHT: 10px; BORDER-TOP: red 2px dotted; PADDING-LEFT: 10px; FONT-SIZE: 9pt; PADDING-BOTTOM: 25px; MARGIN: 5px; BORDER-LEFT: red 2px dotted; WIDTH: 99%; COLOR: brown; LINE-HEIGHT: 1.4em; PADDING-TOP: 10px; BORDER-BOTTOM: red 2px dotted; BACKGROUND-COLOR: #fff">
陆凌牛
</PRE></TD></TR></TBODY></TABLE></DIV>
<P><BR> 诚如您所见,Main方法中并不知道在GetObjectA方法中返回了什么类型的对象,利用反射功能,可以得到返回对象的字段的值。也就是说,这就是所谓的“动态”处理。<BR></P>
<P> 在C#4.0中导入了dynamic类型,可以大幅度简化这种操作。<BR><BR></P>
<DIV style="BORDER-RIGHT: #600 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #600 0px solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; BACKGROUND: #fdd no-repeat left top; PADDING-BOTTOM: 10px; BORDER-LEFT: #600 0px solid; WIDTH: 99%; COLOR: darkred; PADDING-TOP: 10px; BORDER-BOTTOM: #600 0px solid"><FONT style="FONT-SIZE: 16px"><FONT style="FONT-SIZE: 14px">使用dynamic类型访问对象的成员信息<BR></FONT></FONT>
<TABLE style="TABLE-LAYOUT: fixed; FONT-WEIGHT: normal; WIDTH: 100%; FONT-FAMILY: ">
<TBODY>
<TR>
<TD><PRE style="BORDER-RIGHT: red 2px dotted; PADDING-RIGHT: 10px; BORDER-TOP: red 2px dotted; PADDING-LEFT: 10px; FONT-SIZE: 9pt; PADDING-BOTTOM: 5px; MARGIN: 1px; BORDER-LEFT: red 2px dotted; WIDTH: 99%; COLOR: brown; LINE-HEIGHT: 1.4em; PADDING-TOP: 10px; BORDER-BOTTOM: red 2px dotted; BACKGROUND-COLOR: #fff">
<BR>
<FONT color=#a52a2a>using System;</FONT><BR>
<FONT color=#a52a2a>class A<BR>
{<BR>
public readonly string MyName = "陆凌牛";<BR>
public static dynamic GetObjectA() { return new A(); }<BR>
}</FONT><BR>
<FONT color=#a52a2a>class Program<BR>
{<BR>
static void Main(string[] args)<BR>
{<BR>
dynamic a = A.GetObjectA();<BR>
Console.WriteLine(a.MyName);<BR>
}<BR>
}</FONT>
</PRE></TD></TR></TBODY></TABLE></DIV>
<P><BR> 当然,在Main中仍然不知道GetObjectA方法返回的对象为A类型,但仍然可以得到MyName这个字段的值。这是因为,只要名字保持一致,就可以进行访问了,与反射中的访问功能是相同的。<BR><BR> 也就是说,因为名字是否一致不是在编译时检查的,而是在运行时检查的。即使不一致,也不是编译时错误,而是运行时抛出异常。同时,运行时因为要寻找与给定名字相同的成员,运行速度会有相应的延迟。<BR><BR><STRONG><FONT size=5>■ 统一调用</FONT></STRONG><BR><FONT style="FONT-SIZE: 14px" size=5> dynamic类型的特征之一为,虽然不知道对象的类型也可以对对象进行访问,但在某种情况下即使知道了对象的类型,也必须通过dynamic类型进行访问。<BR></FONT></P>
<P><FONT style="FONT-SIZE: 14px" size=5> 下例为两种“鸟”类的定义,这两个类没有继承关系,完全是独立存在的。这种情况下,用普通的方法不能统一调用它们中的某个方法。即使可以另外进行封装,但始终还是要分别针对不同的类分开调用。因为象这样两个没有继承关系的类,要统一调用它们中某个函数是不可能的。但是,现在通过dynamic类型,只要名字,参数与类型保持一致,就可以统一调用了。下例中在统一鸣叫方法中,集中调用了两个类中的同一个方法。<BR></FONT></P>
<DIV style="BORDER-RIGHT: #600 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #600 0px solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; BACKGROUND: #fdd no-repeat left top; PADDING-BOTTOM: 10px; BORDER-LEFT: #600 0px solid; WIDTH: 99%; COLOR: darkred; PADDING-TOP: 10px; BORDER-BOTTOM: #600 0px solid"><FONT style="FONT-SIZE: 16px"><FONT style="FONT-SIZE: 14px">通过dynamic类型进行访问<BR></FONT></FONT>
<TABLE style="TABLE-LAYOUT: fixed; FONT-WEIGHT: normal; WIDTH: 100%; FONT-FAMILY: ">
<TBODY>
<TR>
<TD><PRE style="BORDER-RIGHT: red 2px dotted; PADDING-RIGHT: 10px; BORDER-TOP: red 2px dotted; PADDING-LEFT: 10px; FONT-SIZE: 9pt; PADDING-BOTTOM: 5px; MARGIN: 1px; BORDER-LEFT: red 2px dotted; WIDTH: 99%; COLOR: brown; LINE-HEIGHT: 1.4em; PADDING-TOP: 10px; BORDER-BOTTOM: red 2px dotted; BACKGROUND-COLOR: #fff">
<BR>
<FONT color=#a52a2a>using System;</FONT><BR>
<FONT color=#a52a2a>class 黑鸟<BR>
{<BR>
public void 鸣叫()<BR>
{<BR>
Console.WriteLine("我是黑鸟!");<BR>
}<BR>
}</FONT><BR>
<FONT color=#a52a2a>class 白鸟<BR>
{<BR>
public void 鸣叫()<BR>
{<BR>
Console.WriteLine("我是白鸟");<BR>
}<BR>
}</FONT><BR>
<FONT color=#a52a2a>class Program<BR>
{<BR>
private static void 统一鸣叫(dynamic 鸟)<BR>
{<BR>
鸟.鸣叫();<BR>
}</FONT><BR>
<FONT color=#a52a2a> static void Main(string[] args)<BR>
{<BR>
统一鸣叫((dynamic)new 黑鸟());<BR>
统一鸣叫((dynamic)new 白鸟());<BR>
}<BR>
}</FONT>
</PRE></TD></TR></TBODY></TABLE></DIV><BR>
<DIV style="BORDER-RIGHT: #600 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #600 0px solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; BACKGROUND: #dfd no-repeat left top; PADDING-BOTTOM: 10px; BORDER-LEFT: #600 0px solid; WIDTH: 99%; COLOR: darkred; PADDING-TOP: 10px; BORDER-BOTTOM: #600 0px solid">上例的执行结果
<TABLE style="TABLE-LAYOUT: fixed; FONT-WEIGHT: normal; WIDTH: 100%; FONT-FAMILY: ">
<TBODY>
<TR>
<TD><PRE style="BORDER-RIGHT: red 2px dotted; PADDING-RIGHT: 10px; BORDER-TOP: red 2px dotted; PADDING-LEFT: 10px; FONT-SIZE: 9pt; PADDING-BOTTOM: 25px; MARGIN: 5px; BORDER-LEFT: red 2px dotted; WIDTH: 99%; COLOR: brown; LINE-HEIGHT: 1.4em; PADDING-TOP: 10px; BORDER-BOTTOM: red 2px dotted; BACKGROUND-COLOR: #fff">
我是黑鸟!<BR>
我是白鸟!
</PRE></TD></TR></TBODY></TABLE></DIV>