关于Attribute初始化的问题

nk_maquan 2010-05-17 09:36:30
看了不少关于C#中Attribute介绍的文章,都是说attibute实例,是在编译期进行初始化,而不是运行期。

但查阅csdn时发现了下面一段描述:


[Author("H. Ackerman", version = 1.1)]
class SampleClass


is conceptually equivalent to this:


Author anonymousAuthorObject = new Author("H. Ackerman");
anonymousAuthorObject.version = 1.1;


However, the code is not executed until SampleClass is queried for attributes. Calling GetCustomAttributes on SampleClass causes an Author object to be constructed and initialized as above. If the class has other attributes, other attribute objects are constructed similarly. GetCustomAttributes then returns the Author object and any other attribute objects in an array.

实在是感觉有些矛盾,希望有高手能帮助解释一下。
...全文
144 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
noway8881 2010-05-18
  • 打赏
  • 举报
回复
不是编译期的时候初始化的,是在有人利用反射调用Type.GetCustomAttributes的时候,这个方法创建了Attribute.
nk_maquan 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 noway8881 的回复:]
意思就是说内存中没有AuthorAttribute的对象,直到你调用了GetCustomAttribute(Type)方法。具体可以查看System.RuntimeType中的GetCustomAttribute的实现

C# code
public override object[] GetCustomAttributes(Type attributeType, bool inherit)……
[/Quote]
那所谓的编译区间初始化该如何理解啊?
wangxianshou 2010-05-17
  • 打赏
  • 举报
回复
顶楼主一个,占位学习
noway8881 2010-05-17
  • 打赏
  • 举报
回复
意思就是说内存中没有AuthorAttribute的对象,直到你调用了GetCustomAttribute(Type)方法。具体可以查看System.RuntimeType中的GetCustomAttribute的实现
public override object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
{
throw new ArgumentNullException("attributeType");
}
RuntimeType underlyingSystemType = attributeType.UnderlyingSystemType as RuntimeType;
if (underlyingSystemType == null)
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "attributeType");
}
return CustomAttribute.GetCustomAttributes(this, underlyingSystemType, inherit);
}


internal static object[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool inherit)
{
if (type.GetElementType() != null)
{
if (!caType.IsValueType)
{
return (object[]) Array.CreateInstance(caType, 0);
}
return new object[0];
}
if (type.IsGenericType && !type.IsGenericTypeDefinition)
{
type = type.GetGenericTypeDefinition() as RuntimeType;
}
int count = 0;
Attribute[] sourceArray = PseudoCustomAttribute.GetCustomAttributes(type, caType, true, out count);
if (!inherit || (caType.IsSealed && !GetAttributeUsage(caType).Inherited))
{
object[] objArray = GetCustomAttributes(type.Module, type.MetadataToken, count, caType);
if (count > 0)
{
Array.Copy(sourceArray, 0, objArray, objArray.Length - count, count);
}
return objArray;
}
List<object> derivedAttributes = new List<object>();
bool mustBeInheritable = false;
Type elementType = (((caType == null) || caType.IsValueType) || caType.ContainsGenericParameters) ? typeof(object) : caType;
while (count > 0)
{
derivedAttributes.Add(sourceArray[--count]);
}
while ((type != typeof(object)) && (type != null))
{
object[] objArray2 = GetCustomAttributes(type.Module, type.MetadataToken, 0, caType, mustBeInheritable, derivedAttributes);
mustBeInheritable = true;
for (int i = 0; i < objArray2.Length; i++)
{
derivedAttributes.Add(objArray2[i]);
}
type = type.BaseType as RuntimeType;
}
object[] destinationArray = Array.CreateInstance(elementType, derivedAttributes.Count) as object[];
Array.Copy(derivedAttributes.ToArray(), 0, destinationArray, 0, derivedAttributes.Count);
return destinationArray;
}





internal static unsafe object[] GetCustomAttributes(Module decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes)
{
if (decoratedModule.Assembly.ReflectionOnly)
{
throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
}
MetadataImport metadataImport = decoratedModule.MetadataImport;
CustomAttributeRecord[] customAttributeRecords = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken);
Type elementType = (((attributeFilterType == null) || attributeFilterType.IsValueType) || attributeFilterType.ContainsGenericParameters) ? typeof(object) : attributeFilterType;
if ((attributeFilterType == null) && (customAttributeRecords.Length == 0))
{
return (Array.CreateInstance(elementType, 0) as object[]);
}
object[] attributes = Array.CreateInstance(elementType, customAttributeRecords.Length) as object[];
int length = 0;
SecurityContextFrame frame = new SecurityContextFrame();
frame.Push(decoratedModule.Assembly.InternalAssembly);
Assembly lastAptcaOkAssembly = null;
for (int i = 0; i < customAttributeRecords.Length; i++)
{
bool flag2;
bool flag3;
object obj2 = null;
CustomAttributeRecord caRecord = customAttributeRecords[i];
RuntimeMethodHandle ctor = new RuntimeMethodHandle();
RuntimeType attributeType = null;
int namedArgs = 0;
IntPtr signature = caRecord.blob.Signature;
IntPtr blobEnd = (IntPtr) (((void*) signature) + caRecord.blob.Length);
if (FilterCustomAttributeRecord(caRecord, metadataImport, ref lastAptcaOkAssembly, decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, attributes, derivedAttributes, out attributeType, out ctor, out flag2, out flag3))
{
if (!ctor.IsNullHandle())
{
ctor.CheckLinktimeDemands(decoratedModule, decoratedMetadataToken);
}
RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, flag3);
if (flag2)
{
obj2 = CreateCaObject(decoratedModule, ctor, ref signature, blobEnd, out namedArgs);
}
else
{
obj2 = attributeType.TypeHandle.CreateCaInstance(ctor);
if (Marshal.ReadInt16(signature) != 1)
{
throw new CustomAttributeFormatException();
}
signature = (IntPtr) (((void*) signature) + 2);
namedArgs = Marshal.ReadInt16(signature);
signature = (IntPtr) (((void*) signature) + 2);
}
for (int j = 0; j < namedArgs; j++)
{
string str;
bool flag4;
Type type3;
object obj3;
IntPtr ptr1 = caRecord.blob.Signature;
GetPropertyOrFieldData(decoratedModule, ref signature, blobEnd, out str, out flag4, out type3, out obj3);
try
{
if (flag4)
{
if ((type3 == null) && (obj3 != null))
{
type3 = (obj3.GetType() == typeof(RuntimeType)) ? typeof(Type) : obj3.GetType();
}
RuntimePropertyInfo property = null;
if (type3 == null)
{
property = attributeType.GetProperty(str) as RuntimePropertyInfo;
}
else
{
property = attributeType.GetProperty(str, type3, Type.EmptyTypes) as RuntimePropertyInfo;
}
RuntimeMethodInfo setMethod = property.GetSetMethod(true) as RuntimeMethodInfo;
if (setMethod.IsPublic)
{
setMethod.MethodHandle.CheckLinktimeDemands(decoratedModule, decoratedMetadataToken);
setMethod.Invoke(obj2, BindingFlags.Default, null, new object[] { obj3 }, null, true);
}
}
else
{
(attributeType.GetField(str) as RtFieldInfo).InternalSetValue(obj2, obj3, BindingFlags.Default, Type.DefaultBinder, null, false);
}
}
catch (Exception exception)
{
throw new CustomAttributeFormatException(string.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(flag4 ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), new object[] { str }), exception);
}
}
if (!signature.Equals(blobEnd))
{
throw new CustomAttributeFormatException();
}
attributes[length++] = obj2;
}
}
frame.Pop();
if ((length == customAttributeRecords.Length) && (pcaCount == 0))
{
return attributes;
}
if (length == 0)
{
Array.CreateInstance(elementType, 0);
}
object[] destinationArray = Array.CreateInstance(elementType, (int) (length + pcaCount)) as object[];
Array.Copy(attributes, 0, destinationArray, 0, length);
return destinationArray;
}








110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧