What is diff. between abstract class and an interf...
An abstract class is a special kind of class that cannot be instantiated. So the question is why we need a class that cannot be instantiated? An abstract class is only to be sub-classed (inherited from). In other words, it only allows other classes to inherit from it but cannot be instantiated. The advantage is that it enforces certain hierarchies for all the subclasses. In simple words, it is a kind of contract that forces all the subclasses to carry on the same hierarchies or standards.
An interface is not a class. It is an entity that is defined by the word Interface. An interface has no implementation; it only has the signature or in other words, just the definition of the methods without the body. As one of the similarities to Abstract class, it is a contract that is used to define hierarchies for all subclasses or it defines specific set of methods and their arguments. The main difference between them is that a class can implement more than one interface but can only inherit from one abstract class. Since C# doesn’t support multiple inheritance, interfaces are used to implement multiple inheritance.
Feature
Interface
Abstract class
Multiple inheritance
A class may inherit several interfaces.
A class may inherit only one abstract class.
Default implementation
An interface cannot provide any code, just the signature.
An abstract class can provide complete, default code and/or just the details that have to be overridden.
Constants
Only Static final constants.
Both instance and static constants are possible.
Core VS Peripheral
Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface.
An abstract class defines the core identity of a class and there it is used for objects of the same type.
Homogeneity
If the various implementations only share method signatures then it is better to use Interface.
If the various implementations are of the same kind and use common behaviour or status then abstract class is better to use.
Speed
Requires more time to find the actual method in the corresponding classes.
Fast
Adding functionality
If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.
If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
1. INTRODUCTION TO ATTRIBUTES
What Are Attributes?
Attributes are elements that allow you to add declarative information to your programs. This declarative information is used for various purposes during runtime and can be used at design time by application development tools. The paradigm of attributed programming first appeared in the Interface Definition Language (IDL) of COM interfaces. Microsoft extended the concept to Transaction Server (MTS) and used it heavily in COM+. It is a clean approach to associate metadata with program elements and later use the metadata at design, compile or run time to accomplish some common objectives. Attributes can be attached to Class, Methods, Fields, and Assemblies etc., For example, there are attributes such as DllImportAttribute that allow a program to communicate with the Win32 libraries. Another attribute, ObsoleteAttribute, causes a compile-time warning to appear, letting the developer know that a method should no longer be used. When building Windows Forms applications, there are several attributes that allow visual components to be drag-n-dropped onto a visual form builder and have their information appear in the properties grid. Attributes are also used extensively in securing .NET assemblies, forcing calling code to be evaluated against pre-defined security constraints. These are just a few descriptions of how attributes are used in C# programs. The Following sections will give brief introduction on Attribute semantics and types of attributes available.
2. DECLARATION FUNDAMENTALS OF ATTRIBUTES
2.1 Why Attributes?
The reason attributes are necessary is because many of the services they provide would be very difficult to accomplish with normal code. Attributes add what is called metadata to your programs. When your C# program is compiled, it creates a file called an assembly, which is normally an executable or DLL library. Assemblies are self-describing because they have metadata written to them when they are compiled. Via a process known as reflection, a program's attributes can be retrieved from its assembly metadata. Attributes are classes that can be written in C# and used to decorate your code with declarative information. This is a very powerful concept because it means that your can extend your language by creating customized declarative syntax with attributes.
2.2 Declaring Attributes
Attributes are generally applied physically in front of type and type member declarations. They're declared with square brackets, "[" and "]", surrounding the attribute such as the following ObsoleteAttribute attribute:
[ObsoleteAttribute]
The "Attribute" part of the attribute name is optional. So the following is equivalent to the attribute above:
[Obsolete]
You'll notice that the attribute is declared with only the name of the attribute, surrounded by square brackets. Many attributes have parameter lists that allow inclusion of additional information that customizes a program even further.
Only objects whose class inherits from System.Attribute can be used within brackets.For Example the following would cause an error:
[DateTime (2003, 2, 19)]
Public class example
{
// some code…………..
}
When u add an attribute in your code, you are technically creating a new object whose information will be stored in the assembly. If the attribute has a no-argument constructor, you don’t need to use parentheses in your declaration. However as is the case with ObseleteAttribute, attributes can define custom constructors so you can set the state of attribute with more detail.
Attributes can be associated with method, class, fields, assembly etc,. Attributes can be applied for the return value of a method too.
For example, the following code fragment declares four attributes at the class, field, method and parameter level:
[AttributeForTheClass]
class SomeClass
{
[AttributeForTheField]
int SomeField;
[AttributeForTheMethod]
int SomeMethod (
[AttributeForTheParameter] int someParam)
{
...
}
}
2.3 Types of Attributes
.NET framework is littered with attributes and CLR (common language runtime) provides a set of intrinsic attributes that are integrated into the framework. Serializable is an example of intrinsic attribute. Besides the framework supplied attributes, you can also define your own custom attributes to accomplish your goal. When do you define your custom attributes? Attributes are suitable when you have crosscutting concerns. Object Oriented (OO) methodology lacks a modular approach to address crosscutting concerns in objects. Serialization is an example of crosscutting concern. Any object can be either serializable or non-serializable. If, for example, halfway in the development phase you realize that you need to make a few classes serializable, how do you do that? In .NET, you only need to mark them as serializable and provide methods to implement a serialization format. Other crosscutting concerns can be security, program monitoring and recording during debugging, data validation, etc. If you have a concern that affects a number of unrelated classes, you have a crosscutting concern and attributes are excellent candidates to address crosscutting concerns.
Types of Attributes:
1. Intrinsic Attributes
2. Custom Attributes
Intrinsic Attributes are further classified as Runtime Attributes and Compile time attributes.
We will see how to implement intrinsic also custom attributes in the following sections.
2.4. Attribute Parameters
Attribute classes can have positional parameters and named parameters. Each public instance constructor for an attribute class defines a valid sequence of positional parameters for that attribute class. Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.
An attribute consists of an attribute-name and an optional list of positional and named arguments. The positional arguments (if any) precede the named arguments. A positional argument consists of an attribute-argument-expression; a named argument consists of a name, followed by an equal sign, followed by an attribute-argument-expression, which, together, are constrained by the same rules as simple assignment. The order of named arguments is not significant.
The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:
• One of the following types: bool, byte, char, double, float, int, long, short, string.
• The type object.
• The type System.Type.
• An enum type provided it has public accessibility and the types in which it is nested (if any) also have public accessibility.
• Single-dimensional arrays of the above types.
2.5 Compiling Attributes
Fortunately, from the compilation perspective there is nothing that you need to do differently when u add attributes in your C# code. For example, if you look at an assembly that contains attributes in ILDasm you will see something that looks like following figure.
The custom attribute will be stored in a .custom directive. The location of the directive will vary depending on the target stated in the C# code.
Most of the attributes end up in a .custom directive. Interestingly enough, they are known as custom attributes. However there is a special set of attributes that, when present in the code, will end up in other places in the assembly. These are known as pseudo-custom attributes. You declare them in the same way as u declare any other attribute in your C# code, but the end results in the assembly are vastly different.
For example take a look at the following:
[assembly: AssemblyVersion (“1.0.0.0”)]
When u compile your code you won’t find a .custom directive with a type name that contains AssemblyVersionAttribute.
In this case a .ver directive contains the Version information of the assembly. There is a reason why pseudo-custom attributes are stored this way-its more efficient. Pseudo custom attributes don’t have the over head of storing a bunch of bytes that a normal custom attribute requires.Psuedo custom attributes have this special storage consideration because they are extensively used by compilers or CLR.
2.6 Attribute Targets
All .NET programming elements (assemblies, classes, interfaces, delegates, events, methods, members, enum, struct, and so forth) can be targets of attributes. When they are specified at global scope for an assembly or module, they should be placed immediately after all using statements and before any code. Attributes are placed in square brackets by immediately placing them before their targets, as in
[WebMethod]
public string CapitalCity(string country){
//code to return capital city of a country
}
In the absence of any target-specifier, the target of the above attribute defaults to the method it is applied to (CapitalCity). However, for global scoped attributes, the target-specifier must be explicitly specifed, as in
[assembly:CLSCompliant(true)]
Multiple attributes can be applied to a target by stacking one on top of another, or by placing them inside a square bracket and then separating adjacent attributes by commas.
The syntax for attribute targets is as follows:
[target : attribute-list]
Where: target
One of the following: assembly, field, event, method, module, param, property, return, type.
attribute-list
A list of applicable attributes.
When an attribute is defined, it can also state the valid targets that it can be
applied to in code. This is done via the AttributeTargets Enumeration.
The table below describes all the values of AttributeTargets enumeration.
The values of AttributeTargets can be ORed together, so an attribute designer can make any combination of valid targets. The ALL value is supplied if the attribute can be applied to any target.C# defines nine keywords that can be used to apply the attribute to a specific target in code: assembly, event, field, method, module, param, property, return and type. Some of these keywords overlap with the values in AttributeTargets.For example, type can be used on a class, an interface, a structure and a delegate definition;param can be used on only method arguments.
Where an attribute can be applied legally is determined by the implementer of the attribute. An attribute designer uses AttributeTargetsAttribute class on the attribute definition itself to control the attributes valid destinations. For example if you need to make only one method of class to be obsolete u can do like:
However, you cannot make an entire assembly obsolete. The following C# code will cause a compilation error.
Furthermore, the location of the attribute when a target is explicitly given is also important. For example, an assembly level attribute cannot be declared inside a class or namespace; it must exist outside these scopes, as the following code shows:
You’re not limited to applying only one attribute to a given target. For example the following code is valid.
You may however, be limited in terms of how many times you can apply one specific attribute to a particular target. For example, the following code will not compile:
As with the valid target locations, an attribute designer can control if an attribute can be applied to same target multiple times via the AllowMultiple property of the AttributeUsageAttribute class. The default behavior for an attribute is that it will not be a multiuse attribute, because it is unusual for an attribute to be applied to the same target multiple times, but this can be changed.
Finally, attributes can control whether or not their information is inherited in subclasses or overridden methods. For example, if we use BadCountry as a base class:
In this case, the code wont compile because BadInheritedCountry is trying to use an obsolete class.However,if we didn’t set error to true in ObsoleteAttribute’s constructor, not only would the code compile, but clients would be able to do this without getting a warning.ObsoleteAttribute was designed so that its information does not flow to a
Subclass.This choice is up to the creator of attribute.Again, AttributeUsageAttribute is the center of control to determine how an attribute’s information flows in inheritance scenarios.
3. INTRINSIC ATTRIBUTES
.Net provides a set of Intrinsic attributes that are integrated into the .Net framework.
Along with these users can also define their own custom attributes depending on the usage. Intrinsic attributes are again classified according to the usage as follows:
1. RunTime attributes
2. CompileTime attributes.
In this section we will see what intrinsic attributes are and how they are used.
3.1 Types of Intrinsic attributes:
1.RunTime attributes:
Runtime attributes regroup all attributes that influence the behavior of the runtime. The Just In Time (JIT) compiler looks for these attributes to customize the machine specific assembler it produces. Here are two examples how to use them:
The Layout of Structures:
To the surprise of most C++ programmers, when the JIT compiler sees a declaration for a struct, it is not required to respect the order of the fields in memory. Take, for example, this struct:
struct MyStruct
{
public int X;
public string Y;
}
The JIT compiler may decide to put Y before X in memory to simplify the job of the garbage collector. This is not desirable when you need to pass instances of this struct outside .NET. The StructLayout attribute indicates the memory layout of a C# struct. In the following code, the struct is marked as sequential, so the JIT compiler respects the X and Y order.
StructLayout (LayoutKind.Sequential)]
struct MyStruct
{
public int X;
[MarshalAs (UnmanagedType.BStr)]
public string Y;
}
In addition, you can use MarshalAs to specify the corresponding unmanaged representation of fields and parameters.The following table summarizes the runtime attributes.
Attribute Name Description
System.Serializable The type is serializable.
System.Runtime.InteropServices.DllImportAttribute Specifies the DLL name other information for extern methods.
System.Runtime.InteropServices.MarshalAsAttribute Specifies how the field or attribute should be marshaled.
System.Runtime.InteropServices.ComImportAttribute Specifies that the type was previously defined in COM.
System.Runtime.InteropServices.StructLayoutAttribute Specifies the layout of the structure in memory.
System.Runtime.InteropServices.FieldOffsetAttribute Specifies the memory offset of a field in a struct.
System.Runtime.InteropServices.GuidAttribute Specifies the Guid of a COM class or interface.
System.Runtime.InteropServices.InAttribute Indicates that the parameter is "in".
System.Security.Permissions.CodeAccessSecurityAttribute
Specifies code access permission.
System.Security.Permissions.SecurityPermissionAttribute
Specifies a code access permission.
2. CompileTime attributes:
These attributes regroup attributes that participate in the compilation. There are two categories of compile time attributes: attributes that generate errors or warnings and attributes that change the compiled code in some way. This section examines two compile time attributes supported by C# out of the box: Obsolete and Conditional.
Obsolete
This attribute is used to indicate that a type or member should not be used anymore. The compiler then yields a message each time it detects a member or type marked as obsolete.
void Test ()
{
SomeOldMethod ();
}
[Obsolete ("Use something else", /*IsError*/ false)]
void SomeOldMethod ()
{}
Compile the preceding code and you should see the following warning:
c:\...: warning CS0618:
'...SomeOldMethod ()' is obsolete: 'Use something else'
This kind of message is helpful for code maintenance, plus the attribute gives you a nice way to extend the language without polluting the grammar with unnecessary "obsolete" keywords.
Conditional
This attribute tells the C# compiler that method calls should be discarded unless you apply a specified preprocessing identifier to the calling entity.
void Test ()
{
WriteSomeDebugInfo ();
}
[System.Diagnostics.Conditional ("DEBUG")]
void WriteSomeDebugInfo ()
{
//... do something here
}
In debug mode, the compiler preserves the call to WriteSomeDebugInfo because the "DEBUG" preprocessor identifier is applied. In release mode however, the call is removed. This approach is superior to existing C++ preprocessor techniques because it works across compiled assemblies.
Attribute name Description
System.ObsoleteAttribute
A warning or an error will be raised each time this element is used
System.Diagnostics.ConditionalAttribute
The compiler will discard any call to the method unless the preprocessor identifier is defined
System.CLSCompliantAttribute
Raises an error if the element is not CLS compliant
System.AttributeUsageAttribute
Specifies where the attribute can be applied
3.2 Using Intrinsic Attributes
This section deals with ways of using Intrinsic attributes.
Example 1:
We are already familiar with obsolete attribute.
Let’s talk of it in detail.
Obsolete keyword is used to mark a method as Obsolete and instruct the compiler to issue either a error message or warning message while compiling the class. This keyword may precede a method declaration and has following format:
[Obsolete(str,blnType)]
Where str represent string message and blntype is Boolean value indicating error /warning depending on it’s value is true ore false.
Applies To
Any declaration that allows attributes.
Remarks
The Obsolete attribute is a single-use attribute. Obsolete is an alias for System.ObsoleteAttribute.
When an entity marked Obsolete is used in a program, the compiler issues either an error or a warning (depending on iserror) and prints out message.
See the following code:
using System;
class BasicAttributeDemo
{
[Obsolete]
public void MyFirstDeprecatedMethod()
{
Console.WriteLine("Called MyFirstDeprecatedMethod().");
}
[ObsoleteAttribute]
public void MySecondDeprecatedMethod()
{
Console.WriteLine("Called MySecondDeprecatedMethod().");
}
[Obsolete("You shouldn't use this method anymore.")]
public void MyThirdDeprecatedMethod()
{
Console.WriteLine("Called MyThirdDeprecatedMethod().");
}
// make the program thread safe for COM
[STAThread]
static void Main(string[] args)
{
BasicAttributeDemo attrDemo = new BasicAttributeDemo();
attrDemo.MyFirstDeprecatedMethod();
attrDemo.MySecondDeprecatedMethod();
attrDemo.MyThirdDeprecatedMethod();
}
}
The only difference between the two attributes is that MySecondDeprecatedMethod() method contains the "Attribute" in the attribute declaration. Attributes may also have parameters. This adds customized behavior to the ObsoleteAttribute attribute which produces different results from the other ObsoleteAttribute attribute declarations. The results of all three ObsoleteAttribute attributes are shown below. These are the warnings that are emitted by the C# compiler when the program is compiled:
>csc BasicAttributeDemo.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.2292.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
BasicAttributeDemo.cs (29,3): warning CS0612:
‘BasicAttributeDemo.MyFirstDeprecatedMethod ()' is obsolete
BasicAttributeDemo.cs(30,3): warning CS0612:
‘BasicAttributeDemo.MySecondDeprecatedMethod ()' is obsolete
BasicAttributeDemo.cs (31,3): warning CS0618:
‘BasicAttributeDemo.MyThirdDeprecatedMethod ()' is obsolete: 'You
Shouldn’t use this method anymore.'
As you can see, the ObsoleteAttribute attribute caused the MyThirdDeprecatedMethod () method to emit the message that was a parameter to the ObsoleteAttribute attribute of that method in the code. The other attributes simply emitted standard warnings.
4. CUSTOM ATTRIBUTES
Custom attributes are not just useful in providing custom information to our program elements, they serve as a way to explore further into retrieve metadata information on our types, methods etc using Reflection.
4.1 AttributeUsage
To create a custom attribute, you need to associate the class with the intrinsic attribute AtributeUsage attribute. The class should be derived from System.Attribute.
AttributeUsage attribute describes the behavior and capabilities of your custom attribute.
Following is the syntax for defining the AttributeUsage attribute:
[AttributeUsage (AttributeTarget, AllowMultiple=true/false, Inherited=inherited)]
Parameters
validon
Specifies the language elements on which the attribute can be placed; a combination of AttributeTargets values. Default value is AttributeTargets.All.
allowmultiple (optional)
A bool; if true, the attribute is multiuse. Default is false (single-use).
inherited (optional)
A bool; if true, the attribute is inherited by derived classes. Default is false (not inherited).
Applies To
Class declarations.
Remarks
The AttributeUsage attribute is a single-use attribute. AttributeUsage is an alias for System.AttributeUsageAttribute.
4.2 Implementing Custom Attributes
Step 1: Define the attribute class:
The attribute in this example stores the name and level of the programmer.
Using System;
[AttributeUsage (AttributeTargets.All)]
public class Developer : System.Attribute
{
//Private fields.
private string name;
private string level;
public Developer (string name, string level)
{
this.name = name;
this.level = level;
}
public virtual string Name
{
get {return name;}
}
public virtual string Level
{
get {return level;}
}
}
Step 2. Retrieving single instance of Attribute.
The Developer Attribute described above is applied to the following class on the class level
The GetAttribute method uses GetCustomAttribute to retrieve the values stored in DeveloperAttribute on the class level.
using System;
[Developer ("dev", "55")]
class MainApp
{
public static void Main()
{
//Call function to get and display the attribute.
GetAttribute (typeof (MainApp));
}
public static void GetAttribute(Type t)
{
//Get instance of the attribute.
Developer MyAttribute = (Developer) Attribute.GetCustomAttribute(t, typeof (Developer));
if (null == MyAttribute)
{
Console.WriteLine("The attribute was not found.");
}
else
{
//Get the Name value.
Console.WriteLine ("The Name Attribute is: {0}." , MyAttribute.Name);
Console.WriteLine ("The Level Attribute is: {0}." , MyAttribute.Level);
}
}
}
Output of the Code segment:
The Name Attribute is: dev
The Level Attribute is: 55
5. CONCLUSION
Attributes are C# language elements that decorate program elements with additional metadata that describes the program. This metadata is then evaluated at different places, such as runtime or design time for various purposes. Attributes may also be used to decorate various different types of program elements with a target descriptor. Custom attributes provide a powerful way to communicate something about your component. Custom attributes can be user attributes, runtime attributes, or compile time attributes depending on the element of the system they interact with. The main point about attributes is extensibility. Not only can you apply attributes to your code but you can also define your own attribute with your own specific semantic.
REFERENCES:
1. www.msdn.com
2. www.csharpstation.com
3. Professional C# - Wrox publications.
4. Visual Studio .Net Black Book – Julian Templeman.
Thursday, September 25, 2008
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment