Chapter95:Attributes

No Comments

Section95.1:Creatingacustomattribute

//1)AllattributesshouldbeinheritedfromSystem.Attribute

//2)Youcancustomizeyourattributeusage(e.g.placerestrictions)byusingSystem.AttributeUsage Attribute

//3)Youcanusethisattributeonlyviareflectioninthewayitissupposedtobeused

//4)MethodMetadataAttributeisjustaname.Youcanuseitwithout”Attribute”postfix-e.g. [MethodMetadata(“Thistextcouldberetrievedviareflection”)].

//5)Youcanoverloadanattributeconstructors [System.AttributeUsage(System.AttributeTargets.Method|System.AttributeTargets.Class)] publicclassMethodMetadataAttribute:System.Attribute

{

//thisiscustomfieldgivenjustforanexample

//youcancreateattributewithoutanyfields

//evenanemptyattributecanbeused-asmarker

publicstringText{get;set;}

//thisconstructorcouldbeusedas[MethodMetadata]

publicMethodMetadataAttribute()

{

}

//Thisconstructorcouldbeusedas[MethodMetadata(“String”)]

publicMethodMetadataAttribute(stringtext)

{

Text=text;

}

}

Section95.2:Readinganattribute

MethodGetCustomAttributesreturnsanarrayofcustomattributesappliedtothemember.Afterretrievingthis arrayyoucansearchforoneormorespecificattributes.

varattribute=typeof(MyClass).GetCustomAttributes().OfType<MyCustomAttribute>().Single();

Oriteratethroughthem

foreach(varattributeintypeof(MyClass).GetCustomAttributes()){ Console.WriteLine(attribute.GetType());

}

GetCustomAttributeextension method from System.Reflection.CustomAttributeExtensionsretrieves a custom attributeofaspecifiedtype,itcanbeappliedtoanyMemberInfo.

varattribute=(MyCustomAttribute)typeof(MyClass).GetCustomAttribute(typeof(MyCustomAttribute));

GetCustomAttributealsohasgenericsignaturetospecifytypeofattributetosearchfor.

varattribute=typeof(MyClass).GetCustomAttribute<MyCustomAttribute>();

Booleanargumentinheritcanbepassedtobothofthosemethods.Ifthisvaluesettotruetheancestorsof element would be also to inspected.

Section95.3:Usinganattribute

[StackDemo(Text=”Hello,World!”)]

publicclassMyClass

{

[StackDemo(“Hello,World!”)]

staticvoidMyMethod()

{

}

}

Section95.4:DebuggerDisplayAttribute

AddingtheDebuggerDisplayAttributewillchangethewaythedebuggerdisplaystheclasswhenitishoveredover.

Expressions that are wrapped in {}will be evaluated by the debugger. This can be a simple property like in the following sample or more complex logic.

[DebuggerDisplay(“{StringProperty}-{IntProperty}”)]

publicclassAnObject

{

publicintObjectId{get;set;}

publicstringStringProperty{get;set;}

publicintIntProperty{get;set;}

}

Adding,nqbeforetheclosingbracketremovesthequoteswhenoutputtingastring.

[DebuggerDisplay(“{StringProperty,nq}-{IntProperty}”)]

Eventhoughgeneralexpressionsareallowedinthe{}theyarenotrecommended.TheDebuggerDisplayattribute willbewrittenintotheassemblymetadataasastring.Expressionsin{}arenotcheckedforvalidity.Soa DebuggerDisplayattributecontainingmorecomplexlogicthani.e.somesimplearithmeticmightworkfineinC#, butthesameexpressionevaluatedinVB.NETwillprobablynotbesyntacticallyvalidandproduceanerrorwhile debugging.

AwaytomakeDebuggerDisplaymorelanguageagnosticistowritetheexpressioninamethodorpropertyandcall it instead.

[DebuggerDisplay(“{DebuggerDisplay(),nq}”)]

publicclassAnObject

{

publicintObjectId{get;set;}

publicstringStringProperty{get;set;}

publicintIntProperty{get;set;}

privatestringDebuggerDisplay()

{

return$”{StringProperty}-{IntProperty}””;

}

}

OnemightwantDebuggerDisplaytooutputallorjustsomeofthepropertiesandwhendebuggingandinspecting also the type of the object.

The example below also surrounds the helper method with #ifDEBUGas DebuggerDisplayis used in debugging environments.

[DebuggerDisplay(“{DebuggerDisplay(),nq}”)]

publicclassAnObject

{

publicintObjectId{get;set;}

publicstringStringProperty{get;set;}

publicintIntProperty{get;set;}

#ifDEBUG

privatestringDebuggerDisplay()

{

return

$”ObjectId:{this.ObjectId},StringProperty:{this.StringProperty}, Type:{this.GetType()}”;

}

#endif

}

Section95.5:Callerinfoattributes

Caller info attributes can be used to pass down information about the invoker to the invoked method. The declaration looks like this:

usingSystem.Runtime.CompilerServices;

publicvoidLogException(Exceptionex,

[CallerMemberName]stringcallerMemberName=””,

[CallerLineNumber]intcallerLineNumber=0,

[CallerFilePath]stringcallerFilePath=””)

{

//performlogging

}

Andtheinvocationlookslike this:

publicvoidSave(DBContextcontext)

{

try

{

context.SaveChanges();

}

catch(Exceptionex)

{

LogException(ex);

}

}

Notice that only the first parameter is passed explicitly to the LogExceptionmethod whereas the rest of them willbe provided at compile time with the relevant values.

ThecallerMemberNameparameterwillreceivethevalue”Save”-thenameofthecallingmethod.

ThecallerLineNumberparameterwillreceivethenumberofwhicheverlinetheLogExceptionmethodcallis written on.

Andthe’callerFilePath’parameterwillreceivethefullpathofthefileSavemethodisdeclaredin.

Section95.6:ObsoleteAttribute

System.Obsolete is an attribute that is used to mark a type or a member that has a better version, and thus should not be used.

[Obsolete(“Thisclassisobsolete.UseSomeOtherClassinstead.”)]classSomeClass

{

//

}

Incasetheclassaboveisused,thecompilerwillgivethewarning”Thisclassisobsolete.UseSomeOtherClass instead.”

Section95.7:Readinganattributefrominterface

Thereisnosimplewaytoobtainattributesfromaninterface,sinceclassesdoesnotinheritattributesfroman interface.Wheneverimplementinganinterfaceoroverridingmembersinaderivedclass,youneedtore-declare theattributes.SointheexamplebelowoutputwouldbeTrueinallthreecases.

usingSystem;

usingSystem.Linq;

usingSystem.Reflection;

namespaceInterfaceAttributesDemo{

[AttributeUsage(AttributeTargets.Interface,Inherited=true

)] classMyCustomAttribute:Attribute{

publicstringText{get;set;}

}

[MyCustomAttribute(Text=”Hellofrominterfaceattribute”)]

interfaceIMyClass{

voidMyMethod();

}

classMyClass:IMyClass{

publicvoidMyMethod() { }

}

publicclassProgram{

publicstaticvoidMain(string[]args){

GetInterfaceAttributeDemo();

}

privatestaticvoidGetInterfaceAttributeDemo(){

varattribute1=(MyCustomAttribute)

typeof(MyClass).GetCustomAttribute(typeof(MyCustomAttribute),true);

Console.WriteLine(attribute1==null);//True

varattribute2=

typeof(MyClass).GetCustomAttributes(true).OfType<MyCustomAttribute>().SingleOrDefault();

Console.WriteLine(attribute2==null);//True

varattribute3=typeof(MyClass).GetCustomAttribute<MyCustomAttribute>(true); Console.WriteLine(attribute3==null);//True

}

}

}

Onewaytoretrieveinterfaceattributesistosearchforthemthroughalltheinterfacesimplementedbyaclass.

varattribute=typeof(MyClass).GetInterfaces().SelectMany(x=>x.GetCustomAttributes(

).OfType<MyCustomAttribute>()).SingleOrDefault();

Console.WriteLine(attribute==null);//False

Console.WriteLine(attribute.Text);//Hellofrominterfaceattribute

About us and this blog

We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

Request a free quote

We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

Subscribe to our newsletter!

More from our blog

See all posts
No Comments

Recent Posts

Leave a Comment