代码出自《C#高级编程》第11章“反射”,问题在文中红色注释部分。
//===========================
WhatsNewAttribute.cs :
using System;
using System.Collections.Generic;
using System.Text;
namespace hillspring.WhatsNewAttributes
{
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public class LastModifiedAttribute:Attribute
{
private DateTime dateModified;
private string changes;
private string issues;
public LastModifiedAttribute(string dateModified, string changes)
{
this.dateModified = DateTime.Parse(dateModified);
this.changes = changes;
}
public DateTime DateModified
{
get
{
return dateModified;
}
}
public string Changes
{
get
{
return changes;
}
}
public string Issues
{
get
{
return issues;
}
set
{
issues = value;
}
}
}
[AttributeUsage(AttributeTargets.Assembly)]
public class SupportsWhatsNewAttribute : Attribute
{
public void print() { }
}
}
//======================
VectorClass.cs
using System;
using System.Collections.Generic;
using System.Text;
using hillspring.WhatsNewAttributes;
using System.Collections;
[assembly: SupportsWhatsNewAttribute]
namespace hills.VectorClass
{
[LastModifiedAttribute("24 Nov 2006", "IEnumerable interface implemented" ,Issues="So Vector can now be treated as a collection")]
[LastModifiedAttribute("24 Nov 2006", "IFormattable interface implemented", Issues = "So Vector responds to format specifies N and VE")]
class Vector:IFormattable, IEnumerable
{
public double x, y, z;
public Vector(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
[LastModifiedAttribute("24 Nov 2006", "Method added in order to provider formatting support")]
public string ToString(string format, IFormatProvider formatProvider)
{
return null;
}
public IEnumerator GetEnumerator()
{
return null;
}
public SupportsWhatsNewAttribute testtest
{
get
{
SupportsWhatsNewAttribute sss = new SupportsWhatsNewAttribute();
return sss; }
}
}
}
//==========================
WhatsNewAttributes.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using hillspring.VectorClass;
using hillspring.WhatsNewAttributes;
using System.Reflection;
namespace hillspring.LookUpWhatsNew
{
class LookUpWhatsNew
{
static StringBuilder outputText = new StringBuilder(1000);
static DateTime backDateTo = new DateTime(2006, 1, 1);
static void Main()
{
Assembly theAssembly = Assembly.Load("VectorClass");
Attribute supportsAttribute = (SupportsWhatsNewAttribute)Attribute.GetCustomAttribute(theAssembly, typeof(hillspring.WhatsNewAttributes.SupportsWhatsNewAttribute));
//为什么supportsAttribute为null ?
string name = theAssembly.FullName;
AddToMessage("Assembly: " + name);
if (supportsAttribute == null)
{
AddToMessage("This assembly does not support WhatsNew Attribute");
return;
}
else
{
AddToMessage("Defined Types: ");
}
/*
MemberInfo mInfo = typeof(Vector);
SupportsWhatsNewAttribute supportsAttribute1 = (SupportsWhatsNewAttribute)Attribute.GetCustomAttribute(mInfo, typeof(SupportsWhatsNewAttribute));
//类型转换之后,supportsAttribute1为什么仍旧是null ?
LastModifiedAttribute[] lastModifiedAttribute1 = (LastModifiedAttribute[])Attribute.GetCustomAttributes(mInfo, typeof(LastModifiedAttribute));
Console.WriteLine(lastModifiedAttribute1[0].Changes);
//lastModifiedAttribute1 类型转换正常!为什么此处正常,而其他地方的转换不正常呢?
*/
Type[] types = theAssembly.GetTypes();
foreach (Type definedType in types)
{
DisplayTypeInfo(theAssembly, definedType);
}
MessageBox.Show(outputText.ToString(), "What/'s New since " + backDateTo.ToLongDateString());
Console.ReadLine();
}
static void DisplayTypeInfo(Assembly theAssembly, Type type)
{
if(!(type.IsClass))
return;
AddToMessage("/n class: "+type.Name);
Attribute[] attributes = Attribute.GetCustomAttributes(type);
//LastModifiedAttribute[] attributes = (LastModifiedAttribute[])Attribute.GetCustomAttributes(type);
//为什么无法强制类型转换?编译不出现错误,运行阶段报错。
if (attributes.Length == 0)
AddToMessage("No changes to this class/n");
else
{
foreach (Attribute attribute in attributes)
{
//Console.WriteLine(((LastModifiedAttribute)attribute).Changes);
//WriteAttributeInfo((LastModifiedAttribute)attribute);//为什么无法强制类型转换?编译不出现错误,
//运行阶段报错。
WriteAttributeInfo(attribute);
}
}
MethodInfo[] methods = type.GetMethods();
AddToMessage("changes to methods of this class");
foreach(MethodInfo nextMethod in methods)
{
object[] attribs2 = nextMethod.GetCustomAttributes(typeof(LastModifiedAttribute),false);
if (attributes != null)
{
AddToMessage(nextMethod.ReflectedType+" "+nextMethod.Name+"()");
foreach(Attribute nextAttrib in attribs2)
{
WriteAttributeInfo((LastModifiedAttribute)nextAttrib);
}
}
}
}
static void WriteAttributeInfo(Attribute attrib)
{
LastModifiedAttribute lastModifiedAttribute = attrib as LastModifiedAttribute;
//为什么转换出的lastModifiedAttribute=null?
//LastModifiedAttribute lastModifiedAttribute1 = (LastModifiedAttribute)attrib;//无法强制类型转换;
if (lastModifiedAttribute == null)
return;
DateTime modifiedDate = lastModifiedAttribute.DateModified;
if (modifiedDate < backDateTo)
return;
AddToMessage(" Modified: "+modifiedDate.ToLongDateString()+":");
AddToMessage(" " + lastModifiedAttribute.Changes);
if (lastModifiedAttribute.Issues != null)
{
AddToMessage(" Outstanding issues:"+lastModifiedAttribute.Issues);
}
}
static void AddToMessage(string Msg)
{
outputText.Append("/n"+Msg);
}
}
}