c# attribute介绍


C# introduced attributes, which allow you to embed information right into the C# source code. Attributes are placed in square brackets.

[STAThreadAttribute]
public static int Main(string[] args) {
}
Indicates that the default threading model for an application is single-threaded apartment.  Here the Attribute Target is Method.  It also implies that there is a class (implemented by the environment in this case) by the name of STAThreadAttribute, with a parameter-less constructor STAThreadAttribute()
[MTAThread] [MTAThread] is short for [MTAThreadAttribute], in C#. In other words "Attribute" suffix is optional.  If you are working in a mixed environment, you should use the full name MTAThreadAttribute versus the shortcut MTAThread.
[Obsolete] [Obsolete] can be used to mark an Attribute Target as obsolete.  The compiler picks this attribute and emits a message or generates an error
[AttributeUsageAttribute(AttributeTargets.Field)]
public class PrecisionAttribute {
    public void PrecisionAttribute(int length, int precision) {
    }
}
Indicates that the user defined attribute PrecisionAttribute can be applied to fields only. It also indicates that there is a constructor of name AttributeUsageAttribute(AttributeTargets t) in a class AttributeUsageAttribute. Again this class AttributeUsageAttribute is implemented by the .Net environment.
[PrecisionAttribute(7, 3)] or
[Precision(7, 3)]
Indicates that there is a constructor of name PrecisionAttribute(int, int) in a class PrecisionAttribute, possibly implemented by you.
[In] or [InAttribute] Both mean the same thing.
[InAttribute, Out, CustomMarshaller(true, UnmanagedType.U4))]
TraderIdentifier trId
or
[In] [Out]
[CustomMarshaller(true, UnmanagedType.U4)]
TraderIdentifier trId;
Attributes may be combined using the comma separator or listed separately within square brackets.
[DllImport("User32.dll")]
public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
Instructs the compiler to insert code to allow dynamic access to dll.

Sample Code

Here is a sample that shows how to create a custom attribute and code to use the same program.  This simply allows you to store the formatting with the declaration.  For example consider these two examples:

        [Formatting("###-##-####")]
        public int socialSecurityNumber;
       
        [FormattingAttribute("(###) ###-####")]
        public long phoneNumber;

Class hierarchy

Here is the class hierarchy for the sample code. 

Class AttributeSample houses the main function. FormattingAttribute is the code for the attribute and contains a private class Core with core functionality.  Classes Person, USCitizen, USEmployee implement the ISupportsFormatting interface and the hierarchical relationship between them is shown in the class hierarchy below. ISupportsFormatting requires methods string Fields() and string Field (string field) to be implemented by the class implementing the interface.

Code

Here is the code sample in it's entirety. Enjoy ! 

Let me know what you think or if you can find a sharp use of C# attributes.

Dickey B. Singh, 
<script language="javascript" type="text/javascript">document.writeln("buv deep" + " @" + "hotmail .com
");</script> buv deep @hotmail .com
Director Software Development
@Road www.road.com


using
System;
using System.Reflection;
using System.Collections;
using System.Text;

namespace AttributeSample {

internal class AttributeSample {
[STAThreadAttribute]
public static int Main(string[] args) {
try {
USEmployee usemployee = new USEmployee("John Doe", 30, 987654321, 8005551212, 36000);

//Write a specific named field
Console.WriteLine(usemployee.Field("socialSecurityNumber"));

Console.WriteLine("");

//Write all fields
Console.WriteLine(usemployee.Fields());



Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("Paused... Press any key.");

Console.Read();
                

} catch (Exception x){
Console.WriteLine(x.Message);
Console.WriteLine(x.StackTrace);
return -1;
}
return 1;
}
}


internal class Person: ISupportsFormatting {
public string name;

[FormattingAttribute("### years")]
public int age;

[FormattingAttribute("0#/0#/####")]
public int someImportantDate = 09241972;

[Formatting("0.###E+000")]
//You may use 'Formatting' instead of 'FormattingAttribute', in C#.
//FormattingAttribute is recommended, if you also program in languages like C++
public long someUselessLongValue;

public Person(string name, int age) {
someUselessLongValue = -1234567890123456789;
this.name = name;
this.age = age;
}

public string Fields() {
return FormattingAttribute.FormattedMembersToString(this);
}

public string Field(string field) {
return FormattingAttribute.FormattedMembers(this, field);
}

}

internal class USCitizen : Person, ISupportsFormatting {
[FormattingAttribute("###-##-####")]
public int socialSecurityNumber;

[FormattingAttribute("(###) ###-####")]
public long phoneNumber;

public USCitizen(string name, int age, int socialSecurityNumber, long phoneNumber) : base(name, age) {
this.phoneNumber = phoneNumber;
this.socialSecurityNumber = socialSecurityNumber;
}

}

internal class USEmployee : USCitizen, ISupportsFormatting{

[FormattingAttribute("00#")]
public readonly int[] intArray = {1, 17, 9, 141, 12};

[FormattingAttribute("000.0#")]
public readonly long[] longArray = {1, 17, 9, 1410008974574645367, 12};

[FormattingAttribute("$#,#")]
public int yearlySalary;

public USEmployee(string name, int age, int ssn, long ph, int sal) : base(name, age, ssn, ph) {
yearlySalary = sal;
}

}

internal interface ISupportsFormatting {
string Fields();
string Field(string field);
}

[AttributeUsageAttribute(AttributeTargets.Field)]
internal class FormattingAttribute : System.Attribute {
public string format;

public FormattingAttribute(string format) {
this.format = format;
}

public static string FormattedMembers(object o, string caseSensitiveFieldName) {
if (caseSensitiveFieldName == null)
throw new NullReferenceException();
return Core.FormattedMembers(o, caseSensitiveFieldName)[0];
}

public static string[] FormattedMembers(object o) {
return Core.FormattedMembers(o, null);
}

public static string FormattedMembersToString(object o) {
string sReturn = null;
foreach(string s in FormattingAttribute.FormattedMembers(o))
sReturn += s + delimiter;
return sReturn;
}

private static string delimiter = "/n";
public static string Delimiter {
set {
delimiter = (value == null || value.Length == 0)?"/n":value;
}
get {
return delimiter;
}
}

private class Core {
public static string[] FormattedMembers(object o, string caseSensitiveFieldName) {
if (o == null)
throw new NullReferenceException();

// select the binding flags
BindingFlags bindingflags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance;

//get the member info array. Also look up the Hierarchy
MemberInfo[] memberInfos = o.GetType().GetMembers(bindingflags);

ArrayList a = new ArrayList(memberInfos.GetLength(0));

//only care for public non-static members in this sample.
foreach(MemberInfo mi in memberInfos) {

//allow overloads to work as intended
if (caseSensitiveFieldName != null && caseSensitiveFieldName != mi.Name)
continue;

//don't care for anything other than fields in this sample
if (mi.MemberType != MemberTypes.Field)
continue;

//Get the value & type of the field, e.g. 5 in "[FormattingAttribute("###")] int a = 5;"
object field = Field(o, mi.Name);

//Get the format e.g. "###" in "[FormattingAttribute("###")] int a = 5;"
string format = Formatting(mi);

//now simply write to console or create a string[] to return
a.Add(FieldToLine(field, mi.DeclaringType.ToString(), mi.Name, format));
}
Array strs = Array.CreateInstance(typeof(string), a.Count);
a.CopyTo(strs);
a.Clear();

return (string[])strs;
}
            private static string FieldToLine(object field, string declaringClass, string name, string format) {
//Format the class name
StringBuilder sb = new StringBuilder("("+declaringClass + ") ");

if (field == null) {
sb.Append(name + " = null");
return sb.ToString();
}

sb.Append(field.GetType() + " <" + format + "> " + name + " = ");
if (field.GetType().ToString().EndsWith("[]")) {
System.Array array = field as System.Array;
if (array == null)
sb.Append ("null");
else {
int len = array.Length;
if (len>0)
sb.Append("{");
for(int i=0; i<len; i++) {
sb.Append(FormatObject(array.GetValue(i), format));
sb.Append((i==len-1)?"}":", ");
}
}
} else {
sb.Append(FormatObject(field, format));
}
return sb.ToString();
}

private static string FormatObject(object o, string format) {
if (typeof(int) == o.GetType())
return Convert.ToInt32(o).ToString(format);
if (typeof(long) == o.GetType())
return Convert.ToInt64(o).ToString(format);
return o.ToString();
}

private static object Field(object o, string s) {
try {
return o.GetType().InvokeMember(s, BindingFlags.Instance |
BindingFlags.Public | BindingFlags.GetField, null, o, new object [] {});
} catch (Exception x) {
Console.WriteLine("Error writing object" + o + " " + s);
Console.WriteLine(x.Message);
Console.WriteLine(x.StackTrace);
}
return null;
}

private static string Formatting(MemberInfo mi) {
//Is there a FormattingAttribute associated with "[FormattingAttribute("###")] int a = 5;"
FormattingAttribute a = (FormattingAttribute)Attribute.GetCustomAttribute(mi, typeof(FormattingAttribute));

//Get the format e.g. "###" in "[FormattingAttribute("###")] int a = 5;"
if (a != null)
return a.format;

return string.Empty;
}

}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值