How to Use Attributes in C#

Using Attributes in C#

Introduction

Usinng an attribute is a way to add special meaning to our method and cause it to act in a certain way. Before this was available, developers didn't have a way to define their own attributes. DotNet paved the way for developers and opened new horizons to conquer. Attributes are like adding behaviours to methods, classes, properties structures, events, modules, and so forth. It means we can enforce certain constraints on those methods, classes, properties and vice-versa to behave in the way specify to them.

One more added feature is that, before DotNet, if we made a class or DLL and a newer version came along, the older version that should be removed or should not be used still exists. This causes a problem called DLL Hell. DotNet solved this problem by the concept of versioning. This means that the same DLL with the same name, containing some new methods with older methods can co-exist with a different version number.

Let us start to learn to use attributes in C# code:

Case 1

I had a method in my old DLL. Now, I have updated my DLL and added two new methods and one new method that is the upgraded version of previous DLL.

What should happen is that my previous programs that use this DLL should work properly. Or, if I intend to use the old method in the new program, it should tell me that the old method is obsolete and I should use the new method.

Before DotNet, this wasn't possible. DotNet has removed this hurdle from the path of developers. Let us see how can we do this stuff:

Using System;
Namespace MyExample
{
   Class MyAttribute
   {
      [Obsolete()]
      public static void SaySomething(string str)
      {
         Console.WriteLine(str);
      }
      public static void Talk(string str)
      {
         Console.WriteLine(str);
      }

      static void Main()
      {
         SaySomething("Hello to Sufyan");
         Console.ReadLine();
      }
   }
}

Here, when we call SaySomething("Hello to Sufyan"), it will execute the code but in the output window a warning message will be displayed, showing us that the SaySomething method is obsolete.

Still, it doesn't ask us to use the new talk method SaySomething instead. To display a customized message, we will customize the obsolete attribute like this:

[Obsolete("SaySomething() method is now Obsolete.
          Please use Talk()")]

By using this approach, we can add additional meaning to our attribute.

Note: We can have multiple attribute statements before a method or class. In such cases, if one of the statements is true, it will allow access to that particular method.

There are many attributes that come with DotNet.

  • Conditional
  • DllImport
  • Obsolete
  • Serializable

Conditional attribute

By using the Conditional attribute, we are following a scenario that if a particular condition is true, the user will have access to that specific method. Suppose you wanted your specific method to run only if Internet Explorer is found on the system. Applying this type of security on a method was not easy in the past. Now, it is possible by applying conditional attributes.

Case 2

Suppose you want a method to run if program is in Debug mode. We will write the conditional statement as follows:

[Conditional(.DEBUG.)]
public static void Help(String str)
{
   Console.WriteLine(str);
}

If one calls this method in Main(), it will run only if the program is in Debug mode. If you turn it off in the release mode, it will not run.

DLL Import

Before DotNet, if one wanted to access the core Windows API, he could add a reference and use the library provided by Windows SDK. In DotNet, if we want to access those core features of DotNet, we use DllImport. Component DLLs aren't accessed this way. They are accessed by making a reference to them. Normal DLLs are accessed by using the DllImport attribute.

Case 3

using System;
System.Runtime.InteropServices;
class Beeper
{
   [DllImport(.kernel32.dll.)]
   Public static extern bool Beep(int frequency,int duration);
   static void Main()
   {
      Beep(1000,111);
   }
}

So far, we have learned how to use attributes in DotNet. Still, we haven't learn how to create our own custom attributes with specified behaviour that we assign.

Steps in Creating a Custom Attribute

  1. Define the attribute's usage.
  2. Extend our class with AttributeClass.
  3. Define the behaviours to the class.

Attribute behaviours can be of these types:

  • All—Any application element
  • Assembly—Attribute can be applied to an assembly
  • Class—Attribute can be applied to a class
  • Constructor—Attribute can be applied to a constructor
  • Delegate—Attribute can be applied to a delegate
  • Enum—Attribute can be applied to an enumeration
  • Event—Attribute can be applied to an event
  • Field—Attribute can be applied to a field
  • Interface—Attribute can be applied to an interface
  • Method—Attribute can be applied to a method
  • Module—Attribute can be applied to a module
  • Parameter—Attribute can be applied to a parameter
  • Property—Attribute can be applied to a property
  • ReturnValue—Attribute can be applied to a return value
  • Struct—Attribute can be applied to a structure

The second step is to extend the class with the Attribute class. Basically, our attribute is a class that defines the behaviours of our attribute. For example:

...
public class MySpecialAttribute:Attribute
{...

A point to be noted here is that the name of Attribute we are going to make is MySpecial. We didn't suffix the word Attribute after MySpecial. DotNet automatically suffixed it.

Let us create a sample custom attribute that will execute the method if the regKey provided to the Attribute parameter is correct:

using System;
namespace RegKeyAttributeTestor
{
   [AttributeUsage(AttributeTargets.Method|AttributeTargets.Struct,
                   AllowMultiple=false,Inherited=false]
   public class MyAttribute:Attribute
   {
      private string regKey="a12nf";
      public MyAttribute(string regKey)
      {
         if(this.regKey==regKey)
         {
            Console.WriteLine("Permitted to use this App");
         }
         else
         {
            Console.WriteLine("Not registered to use this App");
         }
      }
   }    //End Attribute class code
   class useAttrib
   {
      [MyAttribute("hello")]
      public static string SayHello(string str)
      {
         return str;
      }
      static void Main()
      {
         Console.WriteLine(SayHello("Hello to Sufyan"));
         Console.ReadLine();
      }
   }

}
AttributeUsage(AttributeTargets.Method|AttributeTargets.Struct,
               AllowMultiple=false, Inherited=false)]

Here, multiple Attribute targets are declared by using "|" between different targets. Allows multiple=false means multiple attributes can be used with this attribute. Inherited=false shows that if some class extends a class that uses this attribute and calls a method that is bound to this attribute, that class has no access to this attribute unless this property is set to true.

Reading Metadata from Assemblies

We first write our custom attribute:

using System;

namespace Sufyan
{
   [AttributeUsage(AttributeTargets.Method,AllowMultiple=false,
                   Inherited=false)]
   public class RegKeyAttribute : Attribute
   {
      private string regKey;

      public RegKeyAttribute(string VRegKey)
      {
         this.regKey = VRegKey;
         if (this.regKey==.hello.)
         {
            Console.WriteLine("Aha! You're Registered");
         }
         else
         {
            Console.WriteLine("Oho! You're not Registered");
         }
      }
   }
}

Now, we shall write our code to reference it through Assembly;.

Steps

First, compile the first example as a Class library; it will generate a .dll file. We will place this .dll file in the bin folder of our second example we are going to make now.

using System;
using System.Reflection;
using Sufyan;

namespace AdvancedDotNet1
{
   class Classic
   {
      static void Main(string[] args)
      {
         Assembly suf = Assembly.Load("RegKey");
         Type KIA=suf.GetType();
         []KO=Attribute.GetCustomAttributes(KIA);
         Object Regist =KO[0];
         Console.WriteLine("Registeration Code is :"+
                           Regist.ToString() );
         Console.ReadLine();
      }
   }
}

System.Reflection is used to retrieve info from the assembly metadata.

To use this in another class, verify that a specific method will execute if that particular developer is registered with me and I have issued him the license key to use.

class useAttrib
   {
      [RegKeyAttribute ("hello")]
      public static string SayHello(string str)
      {
         return str;
      }
      static void Main()
      {
         Console.WriteLine(SayHello("Hello to Sufyan"));
         Console.ReadLine();
      }
   }

Have a close look at this code. I have provided the Hello string as a parameter to the attribute. When we run this application, if we pass a string other then "hello", it will say that you are not registered. We can further modify it according to our need.



About the Author

Ali Sufyan

I am a software developer and a Database designer.I love to work in Java and DotNet.Also to crave new paths of technology

Comments

  • Attributes

    Posted by Deepak upadhyay on 05/08/2014 10:42pm

    The keyword static mean that only one instance of given variable exists for a class. they can directly access by using class name.

    Reply
  • Attribute code not getting called...

    Posted by girishso on 10/21/2004 07:47am

    I have created a small project with classes RegKeyAttribute  and useAttrib, but when i execute the code the attribute class code is not getting called for method SayHello() meaning even if i pass [RegKeyAttribute ("XYZ")] the method is getting executed...
    Am I doing something wrong??
    
    Thanks,
    Girish

    • same problem with me

      Posted by niko on 11/12/2012 06:01am

      Hi, I have the same problem. Did you solve yours already. If yes, could you please provide a solution? Thanks

      Reply
    Reply
  • Very Nice Article

    Posted by AliSufyan on 04/23/2004 03:16am

    This is a very nicec article,i learned a lot from this article

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • One of the most foolproof ways for an online system to confirm, "Is it really you?" is by adding two-factor authentication. Modern two-factor solutions have evolved to support new, complex technology models that change how we use data, including cloud computing and bring-your-own-device (BYOD). However, not all two-factor authentication solutions are created equal. This guide walks through some of the key area of differentiation between two-factor authentication solutions and provides some concrete criteria …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds