Csharp/C Sharp/Language Basics/Attribute
Содержание
- 1 A simple attribute example
- 2 Attribute in class inheritance
- 3 Compiles into a library defining the RamdomSupplier attribute and the RandomMethod attribute
- 4 Creating and using a class attribute.
- 5 Define contant and use it in Conditional attribute
- 6 Defining New Attribute Classes
- 7 demonstrates the flags attribute of an enumeration
- 8 Demonstrate the Conditional attribute
- 9 Demonstrate the Obsolete attribute
- 10 How to create a custom attribute
- 11 Illustrates the GetCustomAttributes method
- 12 Illustrates use of the Conditional attribute
- 13 Illustrates use of the Obsolete attribute
- 14 Shows the use of assembly attributes
- 15 Subclass System.Attribute
- 16 Use a named attribute parameter
- 17 Use a property as a named attribute parameter
- 18 Use AttributeUsage
A simple attribute example
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.All)]
class RemarkAttribute : Attribute {
string remarkValue;
public RemarkAttribute(string comment) {
remarkValue = comment;
}
public string remark {
get {
return remarkValue;
}
}
}
[RemarkAttribute("This class uses an attribute.")]
class UseAttrib {
// ...
}
public class AttribDemo {
public static void Main() {
Type t = typeof(UseAttrib);
Console.Write("Attributes in " + t.Name + ": ");
object[] attribs = t.GetCustomAttributes(false);
foreach(object o in attribs) {
Console.WriteLine(o);
}
Console.Write("Remark: ");
// Retrieve the RemarkAttribute.
Type tRemAtt = typeof(RemarkAttribute);
RemarkAttribute ra = (RemarkAttribute)
Attribute.GetCustomAttribute(t, tRemAtt);
Console.WriteLine(ra.remark);
}
}
Attribute in class inheritance
using System;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Threading;
public class Starter {
public static void Main() {
GenericIdentity g = new GenericIdentity("Person1");
GenericPrincipal p = new GenericPrincipal(g,new string[] { "Manager" });
Thread.CurrentPrincipal = p;
MyClass.MethodA();
YClass.MethodA();
}
}
[PrincipalPermission(SecurityAction.Demand, Role = "Manager")]
public class MyClass {
static public void MethodA() {
Console.WriteLine("MyClass.MethodA");
}
}
[PrincipalPermission(SecurityAction.Demand,Role = "Accountant")]
public class YClass : MyClass {
static public void MethodB() {
Console.WriteLine("MyClass.MethodB");
}
}
Compiles into a library defining the RamdomSupplier attribute and the RandomMethod attribute
/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
Example17_5a compiles into a library defining the RamdomSupplier attribute
and the RandomMethod attribute
*/
using System;
// declare an attribute named RandomSupplier
[AttributeUsage(AttributeTargets.Class)]
public class RandomSupplier : Attribute
{
public RandomSupplier()
{
// doesn"t have to do anything
// we just use this attribute to mark selected classes
}
}
// declare an attribute named RandomMethod
[AttributeUsage(AttributeTargets.Method )]
public class RandomMethod : Attribute
{
public RandomMethod()
{
// doesn"t have to do anything
// we just use this attribute to mark selected methods
}
}
//===================================================
/*
Example17_5b implements one class to supply random numbers
*/
// flag the class as a random supplier
[RandomSupplier]
public class OriginalRandom
{
[RandomMethod]
public int GetRandom()
{
return 5;
}
}
//===================================================
/*
Example17_5c implements one class to supply random numbers
*/
using System;
// flag the class as a random supplier
[RandomSupplier]
public class NewRandom
{
[RandomMethod]
public int ImprovedRandom()
{
Random r = new Random();
return r.Next(1, 100);
}
}
// this class has nothing to do with random numbers
public class AnotherClass
{
public int NotRandom()
{
return 1;
}
}
//===================================================
/*
Example17_5d illustrates runtime type discovery
*/
using System;
using System.Reflection;
class Example17_5d
{
public static void Main(string[] args)
{
RandomSupplier rs;
RandomMethod rm;
// iterate over all command-line arguments
foreach(string s in args)
{
Assembly a = Assembly.LoadFrom(s);
// Look through all the types in the assembly
foreach(Type t in a.GetTypes())
{
rs = (RandomSupplier) Attribute.GetCustomAttribute(
t, typeof(RandomSupplier));
if(rs != null)
{
Console.WriteLine("Found RandomSupplier class {0} in {1}",
t, s);
foreach(MethodInfo m in t.GetMethods())
{
rm = (RandomMethod) Attribute.GetCustomAttribute(
m, typeof(RandomMethod));
if(rm != null)
{
Console.WriteLine("Found RandomMethod method {0}"
, m.Name );
}
}
}
}
}
}
}
Creating and using a class attribute.
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class Creator : System.Attribute {
public Creator(string name, string date) {
this.name = name;
this.date = date;
version = 0.1;
}
string date;
string name;
public double version;
}
[Creator("T", "05/01/2001", version = 1.1)]
class MainClass {
static public void Main(String[] args) {
for (int i = 0; i < args.Length; ++i)
System.Console.WriteLine("Args[{0}] = {1}", i, args[i]);
}
}
Define contant and use it in Conditional attribute
#define LOG
using System;
using System.IO;
using System.Diagnostics;
class Starter {
static void Main() {
LogInfo(new StreamWriter(@"c:\logfile.txt"));
}
[Conditional("LOG")]
private static void LogInfo(StreamWriter sr) {
// write information to log file
}
}
Defining New Attribute Classes
using System;
using System.Diagnostics;
using System.Reflection;
[AttributeUsage(AttributeTargets.Class)]
public class ClassAuthorAttribute : Attribute
{
private string AuthorName;
public ClassAuthorAttribute(string AuthorName)
{
this.AuthorName = AuthorName;
}
public string Author
{
get
{
return AuthorName;
}
}
}
[ClassAuthor("AA")]
public class TestClass
{
public void Method1()
{
Console.WriteLine("Hello from Method1!");
}
[Conditional("DEBUG")]
public void Method2()
{
Console.WriteLine("Hello from Method2!");
}
public void Method3()
{
Console.WriteLine("Hello from Method3!");
}
}
public class MainClass
{
public static void Main()
{
TestClass MyTestClass = new TestClass();
MyTestClass.Method1();
MyTestClass.Method2();
MyTestClass.Method3();
object [] ClassAttributes;
MemberInfo TypeInformation;
TypeInformation = typeof(TestClass);
ClassAttributes = TypeInformation.GetCustomAttributes(typeof(ClassAuthorAttribute), false);
if(ClassAttributes.GetLength(0) != 0)
{
ClassAuthorAttribute ClassAttribute;
ClassAttribute = (ClassAuthorAttribute)(ClassAttributes[0]);
Console.WriteLine("Class Author: {0}", ClassAttribute.Author);
}
}
}
demonstrates the flags attribute of an enumeration
using System;
[Flags]
public enum Contribution {
Pension = 0x01,
ProfitSharing = 0x02,
CreditBureau = 0x04,
SavingsPlan = 0x08,
All = Pension | ProfitSharing | CreditBureau | SavingsPlan
}
public class Employee {
private Contribution prop_contributions;
public Contribution contributions {
get {
return prop_contributions;
}
set {
prop_contributions = value;
}
}
}
public class Starter {
public static void Main() {
Employee bob = new Employee();
bob.contributions = Contribution.ProfitSharing | Contribution.CreditBureau;
if ((bob.contributions & Contribution.ProfitSharing)== Contribution.ProfitSharing) {
Console.WriteLine("Bob enrolled in profit sharing");
}
}
}
Demonstrate the Conditional attribute
// Demonstrate the Conditional attribute.
#define TRIAL
using System;
using System.Diagnostics;
public class TestAno {
[Conditional("TRIAL")]
void trial() {
Console.WriteLine("Trial version, not for distribution.");
}
[Conditional("RELEASE")]
void release() {
Console.WriteLine("Final release version.");
}
public static void Main() {
TestAno t = new TestAno();
t.trial(); // call only if TRIAL is defined
t.release(); // called only if RELEASE is defined
}
}
Demonstrate the Obsolete attribute
// Demonstrate the Obsolete attribute.
using System;
public class TestAno1 {
[Obsolete("Use myMeth2, instead.")]
static int myMeth(int a, int b) {
return a / b;
}
// Improved version of myMeth.
static int myMeth2(int a, int b) {
return b == 0 ? 0 : a /b;
}
public static void Main() {
Console.WriteLine("4 / 3 is " + TestAno1.myMeth(4, 3));
Console.WriteLine("4 / 3 is " + TestAno1.myMeth2(4, 3));
}
}
How to create a custom attribute
/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
Example17_3.cs shows how to create a custom attribute
*/
using System;
public class Example17_3
{
public static void Main()
{
UnitTest u;
// retrieve and display the UnitTest attributes of the classes
Console.Write("Class1 UnitTest attribute: ");
u = (UnitTest) Attribute.GetCustomAttribute(
typeof(Class1), typeof(UnitTest));
Console.WriteLine(u.Written());
Console.Write("Class2 UnitTest attribute: ");
u = (UnitTest) Attribute.GetCustomAttribute(
typeof(Class2), typeof(UnitTest));
Console.WriteLine(u.Written());
}
}
// declare an attribute named UnitTest
// UnitTest.Written is either true or false
public class UnitTest : Attribute
{
bool bWritten;
public bool Written()
{
return bWritten;
}
public UnitTest(bool Written)
{
bWritten = Written;
}
}
// apply the UnitTest attribute to two classes
[UnitTest(true)]
public class Class1
{
}
[UnitTest(false)]
public class Class2
{
}
Illustrates the GetCustomAttributes method
/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
Example17_4.cs illustrates the GetCustomAttributes method
*/
using System;
public class Example17_4
{
public static void Main()
{
// retrieve all attributes of Class1
Console.WriteLine("Class1 attributes: ");
object[] aAttributes = Attribute.GetCustomAttributes(
typeof(Class1));
foreach (object attr in aAttributes)
{
Console.WriteLine(attr);
}
}
}
// declare an attribute named UnitTest
// UnitTest.Written is either true or false
public class UnitTest : Attribute
{
bool bWritten;
public bool Written()
{
return bWritten;
}
public UnitTest(bool Written)
{
bWritten = Written;
}
}
// declare another attribute named LifeCycle
// LifeCycle.Stage returns a string
public class LifeCycle : Attribute
{
string sStage;
public string Stage()
{
return sStage;
}
public LifeCycle(string Stage)
{
sStage = Stage;
}
}
// apply the attribues to a class
[UnitTest(true)]
[LifeCycle("Coding")]
public class Class1
{
}
Illustrates use of the Conditional attribute
/*
illustrates use of the Conditional attribute
*/
#define USE_METHOD_1
using System;
using System.Diagnostics;
public class Example17_2
{
[Conditional("USE_METHOD_1")]
public static void Method1()
{
Console.WriteLine("In Method 1");
}
public static void Main()
{
Console.WriteLine("In Main");
Method1();
}
}
Illustrates use of the Obsolete attribute
/*
illustrates use of the Obsolete attribute
*/
using System;
public class Example17_1
{
// warn the user that Method1 is obsolete
[Obsolete("Method1 has been replaced by NewMethod1", false)]
public static int Method1()
{
return 1;
}
// throw an error if the user tries to use Method2
[Obsolete("Method2 has been replaced by NewMethod2", true)]
public static int Method2()
{
return 2;
}
public static void Main()
{
Console.WriteLine(Method1());
Console.WriteLine(Method2());
}
}
Shows the use of assembly attributes
/*
shows the use of assembly attributes
*/
using System;
using System.Reflection;
using System.Windows.Forms;
[assembly:AssemblyVersionAttribute("1.0.0.0")]
[assembly:AssemblyTitleAttribute("Example 16.1")]
public class Example16_1
{
string privateString;
public string inString
{
get
{
return privateString;
}
set
{
privateString = inString;
}
}
public void upper(out string upperString)
{
upperString = privateString.ToUpper();
}
public static void Main()
{
}
}
Subclass System.Attribute
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class AuthorAttribute : System.Attribute
{
private string company;
private string name;
public AuthorAttribute(string name)
{
this.name = name;
company = "";
}
public string Company
{
get { return company; }
set { company = value; }
}
public string Name
{
get { return name; }
}
}
[assembly: Author("Tom", Company = "Ltd.")]
[Author("Tom", Company = "Abc Ltd.")]
class SomeClass { }
[Author("Lena")]
public class SomeOtherClass
{
}
[Author("FirstName")]
[Author("Jack", Company = "Ltd.")]
class MainClass
{
public static void Main()
{
Type type = typeof(MainClass);
object[] attrs = type.GetCustomAttributes(typeof(AuthorAttribute), true);
foreach (AuthorAttribute a in attrs)
{
Console.WriteLine(a.Name + ", " + a.rupany);
}
}
}
Use a named attribute parameter
// Use a named attribute parameter.
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.All)]
class RemarkAttribute : Attribute {
string remarkValue; // underlies remark property
public string supplement; // this is a named parameter
public RemarkAttribute(string comment) {
remarkValue = comment;
supplement = "None";
}
public string remark {
get {
return remarkValue;
}
}
}
[RemarkAttribute("This class uses an attribute.",
supplement = "This is additional info.")]
class UseAttrib {
// ...
}
public class NamedParamDemo {
public static void Main() {
Type t = typeof(UseAttrib);
Console.Write("Attributes in " + t.Name + ": ");
object[] attribs = t.GetCustomAttributes(false);
foreach(object o in attribs) {
Console.WriteLine(o);
}
// Retrieve the RemarkAttribute.
Type tRemAtt = typeof(RemarkAttribute);
RemarkAttribute ra = (RemarkAttribute)
Attribute.GetCustomAttribute(t, tRemAtt);
Console.Write("Remark: ");
Console.WriteLine(ra.remark);
Console.Write("Supplement: ");
Console.WriteLine(ra.supplement);
}
}
Use a property as a named attribute parameter
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// Use a property as a named attribute parameter.
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.All)]
class RemarkAttribute : Attribute {
string remarkValue; // underlies remark property
int pri_priority; // underlies priority property
public string supplement; // this is a named parameter
public RemarkAttribute(string comment) {
remarkValue = comment;
supplement = "None";
}
public string remark {
get {
return remarkValue;
}
}
// Use a property as a named parameter.
public int priority {
get {
return pri_priority;
}
set {
pri_priority = value;
}
}
}
[RemarkAttribute("This class uses an attribute.",
supplement = "This is additional info.",
priority = 10)]
class UseAttrib {
// ...
}
public class NamedParamDemo11 {
public static void Main() {
Type t = typeof(UseAttrib);
Console.Write("Attributes in " + t.Name + ": ");
object[] attribs = t.GetCustomAttributes(false);
foreach(object o in attribs) {
Console.WriteLine(o);
}
// Retrieve the RemarkAttribute.
Type tRemAtt = typeof(RemarkAttribute);
RemarkAttribute ra = (RemarkAttribute)
Attribute.GetCustomAttribute(t, tRemAtt);
Console.Write("Remark: ");
Console.WriteLine(ra.remark);
Console.Write("Supplement: ");
Console.WriteLine(ra.supplement);
Console.WriteLine("Priority: " + ra.priority);
}
}
Use AttributeUsage
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,Inherited = false)]
public class ClassVersionAttribute : System.Attribute {
public ClassVersionAttribute(string target) : this(target, target) {
}
public ClassVersionAttribute(string target,string current) {
m_TargetVersion = target;
m_CurrentVersion = current;
}
private bool m_UseCurrentVersion = false;
public bool UseCurrentVersion {
set {
if (m_TargetVersion != m_CurrentVersion) {
m_UseCurrentVersion = value;
}
}
get {
return m_UseCurrentVersion;
}
}
private string m_CurrentName;
public string CurrentName {
set {
m_CurrentName = value;
}
get {
return m_CurrentName;
}
}
private string m_TargetVersion;
public string TargetVersion {
get {
return m_TargetVersion;
}
}
private string m_CurrentVersion;
public string CurrentVersion {
get {
return m_CurrentVersion;
}
}
}