什么是属性类?
从抽象类System.Attribute派生出来的类(无论是直接的还是间接的)都称为属性类(MSDN中的定义)。
属性类的名称一般都带有Attribute后缀,但使用的时候可以包含也可以忽略,如果你自己起的名字没有这个后缀,则需要全称来区分了。如果不怕输入麻烦,建议还是不管是否有后缀,都输入全称为好,这样可以减少歧义。
在.NET框架中差不多定义了200个Attribute相关类,可见Attribute的应用十分广泛,它的全图在MSDN中如下:
System.Object
System.Attribute
System.AttributeUsageAttribute
System.CLSCompliantAttribute
System.ComponentModel.AmbientValueAttribute
System.ComponentModel.BindableAttribute
System.ComponentModel.BrowsableAttribute
System.ComponentModel.CategoryAttribute
System.ComponentModel.DefaultEventAttribute
System.ComponentModel.DefaultPropertyAttribute
System.ComponentModel.DefaultValueAttribute
System.ComponentModel.DescriptionAttribute
System.ComponentModel.Design.Serialization.DesignerSerializerAttribute
System.ComponentModel.Design.Serialization.RootDesignerSerializerAttribute
System.ComponentModel.DesignerAttribute
System.ComponentModel.DesignerCategoryAttribute
System.ComponentModel.DesignerSerializationVisibilityAttribute
System.ComponentModel.DesignOnlyAttribute
System.ComponentModel.DesignTimeVisibleAttribute
System.ComponentModel.EditorAttribute
System.ComponentModel.EditorBrowsableAttribute
System.ComponentModel.ImmutableObjectAttribute
System.ComponentModel.InheritanceAttribute
System.ComponentModel.InstallerTypeAttribute
System.ComponentModel.LicenseProviderAttribute
System.ComponentModel.ListBindableAttribute
System.ComponentModel.LocalizableAttribute
System.ComponentModel.MergablePropertyAttribute
System.ComponentModel.NotifyParentPropertyAttribute
System.ComponentModel.ParenthesizePropertyNameAttribute
System.ComponentModel.PropertyTabAttribute
System.ComponentModel.ProvidePropertyAttribute
System.ComponentModel.ReadOnlyAttribute
System.ComponentModel.RecommendedAsConfigurableAttribute
System.ComponentModel.RefreshPropertiesAttribute
System.ComponentModel.RunInstallerAttribute
System.ComponentModel.ToolboxItemAttribute
System.ComponentModel.ToolboxItemFilterAttribute
System.ComponentModel.TypeConverterAttribute
System.ContextStaticAttribute
System.Diagnostics.ConditionalAttribute
System.Diagnostics.DebuggableAttribute
System.Diagnostics.DebuggerHiddenAttribute
System.Diagnostics.DebuggerStepThroughAttribute
System.Drawing.ToolboxBitmapAttribute
System.EnterpriseServices.ApplicationAccessControlAttribute
System.EnterpriseServices.ApplicationActivationAttribute
System.EnterpriseServices.ApplicationIDAttribute
System.EnterpriseServices.ApplicationNameAttribute
System.EnterpriseServices.ApplicationQueuingAttribute
System.EnterpriseServices.AutoCompleteAttribute
System.EnterpriseServices.CompensatingResourceManager.ApplicationCrmEnabledAttribute
System.EnterpriseServices.ComponentAccessControlAttribute
System.EnterpriseServices.COMTIIntrinsicsAttribute
System.EnterpriseServices.ConstructionEnabledAttribute
System.EnterpriseServices.DescriptionAttribute
System.EnterpriseServices.EventClassAttribute
System.EnterpriseServices.EventTrackingEnabledAttribute
System.EnterpriseServices.ExceptionClassAttribute
System.EnterpriseServices.IISIntrinsicsAttribute
System.EnterpriseServices.InterfaceQueuingAttribute
System.EnterpriseServices.JustInTimeActivationAttribute
System.EnterpriseServices.LoadBalancingSupportedAttribute
System.EnterpriseServices.MustRunInClientContextAttribute
System.EnterpriseServices.ObjectPoolingAttribute
System.EnterpriseServices.PrivateComponentAttribute
System.EnterpriseServices.SecureMethodAttribute
System.EnterpriseServices.SecurityRoleAttribute
System.EnterpriseServices.SynchronizationAttribute
System.EnterpriseServices.TransactionAttribute
System.FlagsAttribute
System.LoaderOptimizationAttribute
System.Management.Instrumentation.IgnoreMemberAttribute
System.Management.Instrumentation.InstrumentationClassAttribute
System.Management.Instrumentation.InstrumentedAttribute
System.Management.Instrumentation.ManagedNameAttribute
System.MTAThreadAttribute
System.NonSerializedAttribute
System.ObsoleteAttribute
System.ParamArrayAttribute
System.Reflection.AssemblyAlgorithmIdAttribute
System.Reflection.AssemblyCompanyAttribute
System.Reflection.AssemblyConfigurationAttribute
System.Reflection.AssemblyCopyrightAttribute
System.Reflection.AssemblyCultureAttribute
System.Reflection.AssemblyDefaultAliasAttribute
System.Reflection.AssemblyDelaySignAttribute
System.Reflection.AssemblyDescriptionAttribute
System.Reflection.AssemblyFileVersionAttribute
System.Reflection.AssemblyFlagsAttribute
System.Reflection.AssemblyInformationalVersionAttribute
System.Reflection.AssemblyKeyFileAttribute
System.Reflection.AssemblyKeyNameAttribute
System.Reflection.AssemblyProductAttribute
System.Reflection.AssemblyTitleAttribute
System.Reflection.AssemblyTrademarkAttribute
System.Reflection.AssemblyVersionAttribute
System.Reflection.DefaultMemberAttribute
System.Resources.NeutralResourcesLanguageAttribute
System.Resources.SatelliteContractVersionAttribute
System.Runtime.CompilerServices.AccessedThroughPropertyAttribute
System.Runtime.CompilerServices.CompilationRelaxationsAttribute
System.Runtime.CompilerServices.CompilerGlobalScopeAttribute
System.Runtime.CompilerServices.CustomConstantAttribute
System.Runtime.CompilerServices.DecimalConstantAttribute
System.Runtime.CompilerServices.DiscardableAttribute
System.Runtime.CompilerServices.IndexerNameAttribute
System.Runtime.CompilerServices.MethodImplAttribute
System.Runtime.CompilerServices.RequiredAttributeAttribute
System.Runtime.InteropServices.AutomationProxyAttribute
System.Runtime.InteropServices.BestFitMappingAttribute
System.Runtime.InteropServices.ClassInterfaceAttribute
System.Runtime.InteropServices.CoClassAttribute
System.Runtime.InteropServices.ComAliasNameAttribute
System.Runtime.InteropServices.ComCompatibleVersionAttribute
System.Runtime.InteropServices.ComConversionLossAttribute
System.Runtime.InteropServices.ComEventInterfaceAttribute
System.Runtime.InteropServices.ComImportAttribute
System.Runtime.InteropServices.ComRegisterFunctionAttribute
System.Runtime.InteropServices.ComSourceInterfacesAttribute
System.Runtime.InteropServices.ComUnregisterFunctionAttribute
System.Runtime.InteropServices.ComVisibleAttribute
System.Runtime.InteropServices.DispIdAttribute
System.Runtime.InteropServices.DllImportAttribute
System.Runtime.InteropServices.FieldOffsetAttribute
System.Runtime.InteropServices.GuidAttribute
System.Runtime.InteropServices.IDispatchImplAttribute
System.Runtime.InteropServices.ImportedFromTypeLibAttribute
System.Runtime.InteropServices.InAttribute
System.Runtime.InteropServices.InterfaceTypeAttribute
System.Runtime.InteropServices.LCIDConversionAttribute
System.Runtime.InteropServices.MarshalAsAttribute
System.Runtime.InteropServices.OptionalAttribute
System.Runtime.InteropServices.OutAttribute
System.Runtime.InteropServices.PreserveSigAttribute
System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute
System.Runtime.InteropServices.ProgIdAttribute
System.Runtime.InteropServices.StructLayoutAttribute
System.Runtime.InteropServices.TypeLibFuncAttribute
System.Runtime.InteropServices.TypeLibTypeAttribute
System.Runtime.InteropServices.TypeLibVarAttribute
System.Runtime.InteropServices.TypeLibVersionAttribute
System.Runtime.Remoting.Messaging.OneWayAttribute
System.Runtime.Remoting.Metadata.SoapAttribute
System.Runtime.Remoting.Proxies.ProxyAttribute
System.Security.AllowPartiallyTrustedCallersAttribute
System.Security.Permissions.SecurityAttribute
System.Security.SuppressUnmanagedCodeSecurityAttribute
System.Security.UnverifiableCodeAttribute
System.SerializableAttribute
System.STAThreadAttribute
System.ThreadStaticAttribute
System.Web.Services.Configuration.XmlFormatExtensionAttribute
System.Web.Services.Configuration.XmlFormatExtensionPointAttribute
System.Web.Services.Configuration.XmlFormatExtensionPrefixAttribute
System.Web.Services.Protocols.HttpMethodAttribute
System.Web.Services.Protocols.MatchAttribute
System.Web.Services.Protocols.SoapDocumentMethodAttribute
System.Web.Services.Protocols.SoapDocumentServiceAttribute
System.Web.Services.Protocols.SoapExtensionAttribute
System.Web.Services.Protocols.SoapHeaderAttribute
System.Web.Services.Protocols.SoapRpcMethodAttribute
System.Web.Services.Protocols.SoapRpcServiceAttribute
System.Web.Services.WebMethodAttribute
System.Web.Services.WebServiceAttribute
System.Web.Services.WebServiceBindingAttribute
System.Web.UI.ConstructorNeedsTagAttribute
System.Web.UI.ControlBuilderAttribute
System.Web.UI.DataBindingHandlerAttribute
System.Web.UI.ParseChildrenAttribute
System.Web.UI.PartialCachingAttribute
System.Web.UI.PersistChildrenAttribute
System.Web.UI.PersistenceModeAttribute
System.Web.UI.TagPrefixAttribute
System.Web.UI.TemplateContainerAttribute
System.Web.UI.ToolboxDataAttribute
System.Web.UI.ValidationPropertyAttribute
System.Xml.Serialization.SoapAttributeAttribute
System.Xml.Serialization.SoapElementAttribute
System.Xml.Serialization.SoapEnumAttribute
System.Xml.Serialization.SoapIgnoreAttribute
System.Xml.Serialization.SoapIncludeAttribute
System.Xml.Serialization.SoapTypeAttribute
System.Xml.Serialization.XmlAnyAttributeAttribute
System.Xml.Serialization.XmlAnyElementAttribute
System.Xml.Serialization.XmlArrayAttribute
System.Xml.Serialization.XmlArrayItemAttribute
System.Xml.Serialization.XmlAttributeAttribute
System.Xml.Serialization.XmlChoiceIdentifierAttribute
System.Xml.Serialization.XmlElementAttribute
System.Xml.Serialization.XmlEnumAttribute
System.Xml.Serialization.XmlIgnoreAttribute
System.Xml.Serialization.XmlIncludeAttribute
System.Xml.Serialization.XmlNamespaceDeclarationsAttribute
System.Xml.Serialization.XmlRootAttribute
System.Xml.Serialization.XmlTextAttribute
System.Xml.Serialization.XmlTypeAttribute
System.STAThreadAttribute
大家在一般使用中会留意到这个属性吗?用VS.NET新建一个项目,往往在main前面会如下面所示:
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static
void
Main()
{
Application.Run(new frmMain());
}
其实这个就是属性类STAThreadAttribute了,它的作用表示应用程序的COM线程模型是单线程单元(STA)。
属性类的实用性:
1.利用XML相关的属性类,将相关业务类XML序列化,可以达到保存状态和远程传输交换类信息等作用。
共14个和XML相关的属性类:
System.Xml.Serialization.XmlAnyAttributeAttribute
System.Xml.Serialization.XmlAnyElementAttribute
System.Xml.Serialization.XmlArrayAttribute
System.Xml.Serialization.XmlArrayItemAttribute
System.Xml.Serialization.XmlAttributeAttribute
System.Xml.Serialization.XmlChoiceIdentifierAttribute
System.Xml.Serialization.XmlElementAttribute
System.Xml.Serialization.XmlEnumAttribute
System.Xml.Serialization.XmlIgnoreAttribute
System.Xml.Serialization.XmlIncludeAttribute
System.Xml.Serialization.XmlNamespaceDeclarationsAttribute
System.Xml.Serialization.XmlRootAttribute
System.Xml.Serialization.XmlTextAttribute
System.Xml.Serialization.XmlTypeAttribute
最近做一个项目,需要将一些界面输入的有一定结构规律的信息保存起来,然后下次需要时候可以调入到对应的界面位置上使用。(其实这个是很多应用都会碰到的)。结构和UI的对应关系可能会经常变动的,而且结构中需要填写的内容不是所有都必须的,直接用关系型数据库来保存似乎不是太好的方案。首先想到就是用XML文件来保存这些信息了,而界面之间的信息显示是有关联的,可以说需要一个缓冲来记录这些信息,想到的就是定义一个类来记录和操作这些信息。这自然遇到一个问题,如何保持类和XML数据的同步呢?
生成的XML文件需要给其它业务来做处理,格式上有一定的规范,对于类来说,信息都保存在字段或者属性那里的,并没有区别,但XML中可能有些信息是Attribute,有些又是Element的。如何灵活地处理这些关系呢?用与XML相关的属性来定义这些字段和类就可以了。
(1) 类信息序列化到XML文件中的代码
public
void
SerializeObject(
string
filename)
{
XmlSerializer s = new XmlSerializer(typeof(Tables));
TextWriter writer = new StreamWriter(filename);

Tables group = new Tables();
group.GroupID = 10.089f;
group.IsActive = false;

group.HexBytes = new byte[1]
{Convert.ToByte(100)};

Employee x = new Employee();
Employee y = new Employee();

x.Name = "Jack";
y.Name = "Jill";
x.des2 = "Yyyy
";
x.colType = new ColumnType[2];
x.colType[0] = new ColumnType();
x.colType[1] = new ColumnType();
x.colType[0].linkField = "Haaa
";
x.colType[1].linkType = "Zzzz
";
y.Age[0] = 20;
y.Age[1] = 40;

y.Desc = "OK";

group.Employees = new Employee[2]
{x,y};

Manager mgr = new Manager();
mgr.Name = "Sara";
mgr.Level = 4;

mgr.Desc = "Yes";
mgr.aHead = true;
group.Manager = mgr;
group.ExtraInfo = new ArrayList();
group.ExtraInfo.Add(42);
group.ExtraInfo.Add("Answer");

s.Serialize(writer, group);
writer.Close();
}
(2) XML文件信息变成类的信息的代码
public
void
DeserializeObject(
string
filename)
{
FileStream fs = new FileStream(filename, FileMode.Open);
XmlSerializer x = new XmlSerializer(typeof(Tables));
Tables g = (Tables) x.Deserialize(fs);
int i=0;
foreach(Employee e in g.Employees)
{
i = i + 1;
Console.WriteLine("No {0} Name: {1}",i.ToString(),e.Name);
}

Console.WriteLine(g.Manager.Name);
Console.WriteLine(g.GroupID);
Console.WriteLine(g.HexBytes[0]);
}
(3)例子中相关类信息生成的XML文件
<?
xml version="1.0" encoding="utf-8"
?>
<
Tables
xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
>
<
Member
>
<
Employee
AHead
="false"
>
<
Name
>
Jack
</
Name
>
<
Age
>
0
</
Age
>
<
Age
>
0
</
Age
>
<
des2
>
Yyyy
</
des2
>
<
ColumnType
LinkField
="Haaa
"
/>
<
ColumnType
LinkType
="Zzzz
"
/>
</
Employee
>
<
Employee
Desc
="OK"
AHead
="false"
>
<
Name
>
Jill
</
Name
>
<
Age
>
20
</
Age
>
<
Age
>
40
</
Age
>
</
Employee
>
</
Member
>
<
Building
>
10.088999748229981
</
Building
>
<
HexBytes
>
64
</
HexBytes
>
<
IsActive
>
false
</
IsActive
>
<
Manager
Desc
="Yes"
AHead
="true"
>
<
Name
>
Sara
</
Name
>
<
Age
>
0
</
Age
>
<
Age
>
0
</
Age
>
<
Level
>
4
</
Level
>
</
Manager
>
<
ObjectNumber
>
42
</
ObjectNumber
>
<
ObjectString
>
Answer
</
ObjectString
>
</
Tables
>
(4) XML总体框架如何用XML相关属性类描述
public
class
Tables
{
[XmlArray(ElementName = "Member")]
public Employee[] Employees;
[XmlElement(DataType = "double",
ElementName = "Building")]
public double GroupID;

[XmlElement(DataType = "hexBinary")]
public byte [] HexBytes;


[XmlElement(DataType = "boolean")]
public bool IsActive;

[XmlElement(Type = typeof(Manager))]
public Employee Manager;

[XmlElement(typeof(int),
ElementName = "ObjectNumber"),
XmlElement(typeof(string),
ElementName = "ObjectString")]
public ArrayList ExtraInfo;
}
(5) 类的字段信息表示为属性的方法
public
class
Employee
{
public string Name;
[XmlElement(typeof(int))]
public int[] Age = new int[2];
[XmlAttribute(AttributeName = "Desc")]
public string Desc;
[XmlAttribute(AttributeName = "AHead")]
public bool aHead;

public string des2;
[XmlElement(ElementName="ColumnType")]
public ColumnType[] colType;
}
2.自己根据需要定义自己的属性类,例如定义相关业务类和UI的关系。
在使用中,信息不是一个UI就完成的,可能经过了几个UI,或者几个页面去交互,但可能业务的调整,显示的位置或者一些参数可能需要调整的,这些UI的信息能否也定义为类的某些属性?
从.NET的Attribute派生一个客户定制类可以轻松做到这点,定制类只需要从System.Attribute派生即可。
[AttributeUsage(AttributeTargets.Field
|
AttributeTargets.Class,AllowMultiple
=
true
)]
public
class
LayoutAttribute : Attribute
{
string m_desc;
public string OwnPage;
public string GetDesc()
{
return m_desc;
}

public LayoutAttribute(string strDesc)
{
m_desc = strDesc;
}

}
AttributeUsage这个类定义了LayoutAttribute的一些基本信息,例如这里定义了LayoutAttribute适用于字段,类,并且允许重复定义的。
在应用中,可以利用反射机制,将这些定义的信息获取,从而判断应该在界面上如何处理了。
Type myType
=
Type.GetType(
"
testXmlAttr.Manager
"
);
Console.WriteLine(myType.FullName);
FieldInfo myFieldInfo
=
myType.GetField(
"
Level
"
);
object
[] atts
=
myFieldInfo.GetCustomAttributes(
false
);
for
(
int
i
=
0
;i
<
atts.Length;i
++
)
Console.WriteLine(((LayoutAttribute)atts[i]).OwnPage);
例子运行结果:(同时在当前目录下生成testXmlAttr.xml)

例子代码