Monday, June 22, 2009

Interface in C#

An interface can be a member of a namespace or a class and can contain signatures of the following members: Methods, Properties, Indexers, Events. The actual implementation is done in the class that implements the interface.

interface IIntelligence
{
/// Method declaration within the interface
bool intelligent_behavior();

/// Indexer declaration within the interface
object this[int index]
{
get;
set;
}
/// Event declaration within an interface
/// testEvent should also be declared as a delegate before
event testEvent IQEvent;

/// Property declaration within an interface
string IQProperty
{
get{}
set{}
}
}

-> An interface can inherit from one or more base interfaces.
-> A class or struct can inherit more than one interface.
-> An interface cannot contain fields.
-> The interface can't contain constants, data fields, constructors, destructors and static members.
-> Interfaces members are automatically public.
-> When a base type list contains a base class and interfaces, the base class must come first in the list.
-> A class that implements an interface can explicitly implement members of that interface. An explicitly implemented member cannot be accessed through a class instance, but only through an instance of the interface, for example:

interface IPoint
{
// Property signatures:
int x
{ get; set; }

int y
{
get; set; }
}

class Point : IPoint
{
// Fields:
private int _x;
private int _y;

// Constructor:
public Point(int x, int y)
{
_x = x;
_y = y;
}

// Property implementation:
public int x
{
get
{ return _x; }

set
{ _x = value; }
}

public int y
{
get
{ return _y; }
set
{ _y = value; }
}
}

class MainClass
{
static void PrintPoint(IPoint p)
{
Console.WriteLine("x={0}, y={1}", p.x, p.y);
}

static void Main()
{
Point p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}

-> To implement an interface member, the corresponding member on the class must be public, non-static, and have the same name and signature as the interface member.
-> Properties and indexers on a class can define extra accessors for a property or indexer defined on an interface. For example, an interface may declare a property with a get accessor, but the class implementing the interface can declare the same property with both a get and set accessor. However, if the property or indexer uses explicit implementation, the accessors must match.

Using "Is" and "As" Operators to Verify the Implementation of an Interface

"is" keyword is used to verify whether the method exists in the class implementing the given interface or not.

if(human is IIntelligence)

{
IIntelligence humanIQ = (IIntelligence)human;
humanIQ.intelligent_behavior();
}

In the example case above, when you will run it, it will give a warning that "the given expression is always of the provided type" and the validity is also been checked twice: one in using the "is" operator and the other when casting it to the interface type.

But we can also use the "as" operator to cast and check the types more efficiently. The "as" operator returns an object type and null if the type mismatched whereas the "is" operator returns a Boolean value. Here, no warning will be generated.

IIntelligence humanIQ = human as IIntelligence;

if(null != humanIQ)

{
humanIQ.intelligent_behavior();
}

Note: Microsoft STRONGLY recommends that ALL interfaces begin with the character 'I'.

0 comments: