C# Basic (5)

1. When you define an interface and specify that a class is going to make use of that interface in its definition, the class is said to be implementing the interface or inheriting from the interface.

In C#, an interface is a first-class concept that declares a reference type that includes method declarations only.

 

2. Interfaces can contain methods, properties, indexers, and events—none of which are implemented in the interface itself.

In addition to methods, interfaces can define properties, indexers, and events, as shown here:

interface IExampleInterface
{
    // Example property declaration.
    int testProperty { get; }

    // Example event declaration.
    event testEvent Changed;

    // Example indexer declaration.
    string this[int index] { get; set; }
}

 

 

3. Because an interface defines a contract, any class that implements an interface must define each and every item in that interface or the code won’t compile.

Using interfaces, you can implement multiple behavioral characteristics in a single class. In C# you can derive from a single class and, in addition to that inherited functionality, implement as many interfaces as the class needs. For example, if you wanted the editor application to validate the control’s contents, bind the control to a database, and serialize the contents of the control to disk, you would declare your class as follows:

public class MyGrid : ThirdPartyGrid, IValidate, 
                      ISerializable, IDataBound
{

}

 

 

4. The is operator enables you to check at run time whether one type is compatible with another type. It takes the following form, where expression is a reference type:

expression is type

The is operator results in a Boolean value and can, therefore, be used in conditional statements.

using System;

public class FancyControl
{
    protected string Data;
    public string data
    {
        get
        {
            return this.Data;
        }
        set
        {
            this.Data = value;
        }
    }
}

interface ISerializable
{
    bool Save();
}

interface IValidate
{
    bool Validate();
}

class MyControl : FancyControl, IValidate
{
    public MyControl()
    {
        data = "my grid data";
    }

    public bool Validate()
    {
        Console.WriteLine("Validating...{0}", data);
        return true;
    }
}

class IsOperator2App
{
    public static void Main()
    {
        MyControl myControl = new MyControl();

        if (myControl is ISerializable)
        {
            ISerializable ser = (ISerializable)myControl;
            bool success = ser.Save();

            Console.WriteLine("The saving of '{0}' was {1}successful", 
myControl.data, 
(true == success ? "" : "not "));
        }
        else
        {
         Console.WriteLine("The ISerializable interface is not implemented.");
        }
    }
}

 

 

5. The as operator converts between compatible types and takes the following form, where expression is any reference type:

object = expression as type

You can think of the as operator as a combination of the is operator and, if the two types in question are compatible, a cast.

An important difference between the as operator and the is operator is that the as operator sets the object equal to null instead of returning a Boolean value if expression and type are incompatible.

using System;

public class FancyControl
{
    protected string Data;
    public string data
    {
        get
        {
            return this.Data;
        }
        set
        {
            this.Data = value;
        }
    }
}

interface ISerializable
{
    bool Save();
}

interface IValidate
{
    bool Validate();
}

class MyControl : FancyControl, IValidate
{
    public MyControl()
    {
        data = "my grid data";
    }

    public bool Validate()
    {
        Console.WriteLine("Validating...{0}", data);
        return true;
    }
}

class AsOperatorApp
{
    public static void Main()
    {
        MyControl myControl = new MyControl();

        ISerializable ser = myControl as ISerializable;
        if (null != ser)
        {
            bool success = ser.Save();

            Console.WriteLine("The saving of '{0}' was {1}successful", 
myControl.data, 
(true == success ? "" : "not "));
        }
        else
        {
          Console.WriteLine("The ISerializable interface is not implemented.");
        }
    }
}

 

 

6. when a class implements an interface’s methods, those methods are also public methods of the class.

using System;

public interface IDataBound
{
    void Bind();
}

public class EditBox : IDataBound
{
    // IDataBound implementation.
    public void Bind()
    {
        Console.WriteLine("Binding to data store...");
    }
}

class NameHiding1App
{
    // Main entry point.
    public static void Main()
    {
        Console.WriteLine();

        EditBox edit = new EditBox();
        Console.WriteLine("Calling EditBox.Bind()...");
        edit.Bind();

        Console.WriteLine();

        IDataBound bound = (IDataBound)edit;
        Console.WriteLine("Calling (IDataBound)EditBox.Bind()...");
        bound.Bind();
    }
}

Notice that although this application calls the implemented Bind method in two different ways—one with a cast and one without—both calls function correctly in that the Bind method is processed.

You can prevent the implemented members of interfaces from becoming public members of the class by using a technique called name hiding.

Name hidingat its simplest is the ability to hide an inherited member name from any code outside the derived or implementing class (commonly referred to as the outside world).

To hide an implemented interface member, you need only remove the member’s public access modifier and qualify the member name with the interface name, as shown here:

using System;

public interface IDataBound
{
    void Bind();
}

public class EditBox : IDataBound
{
    // IDataBound implementation.
    void IDataBound.Bind()
    {
        Console.WriteLine("Binding to data store...");
    }
}

class NameHiding2App
{
    public static void Main()
    {
        Console.WriteLine();

        EditBox edit = new EditBox();
        Console.WriteLine("Calling EditBox.Bind()...");

        // ERROR: This line won't compile because
        // the Bind method no longer exists in the 
        // EditBox class's namespace.
        edit.Bind();

        Console.WriteLine();

        IDataBound bound = (IDataBound)edit;
        Console.WriteLine("Calling (IDataBound)EditBox.Bind()...");

        // This is OK because the object was cast to 
        // IDataBound first.
        bound.Bind();
}
}

It is also the way to eliminate the name ambiguity.

 

7. Combining Interface

using System;

public class Control
{
}

public interface IDragDrop
{
    void Drag();
    void Drop();
}

public interface ISerializable
{
    void Serialize();
}

public interface ICombo : IDragDrop, ISerializable
{
    // This interface doesn't add anything new in
    // terms of behavior as its only purpose is 
    // to combine the IDragDrop and ISerializable
    // interfaces into one interface.
}

public class MyTreeView : Control, ICombo
{
    public void Drag() 
    { 
        Console.WriteLine("MyTreeView.Drag called"); 
    }

    public void Drop()
    { 
        Console.WriteLine("MyTreeView.Drop called"); 
    }

    public void Serialize()
    { 
        Console.WriteLine("MyTreeView.Serialize called"); 
    }
}

class CombiningApp
{
    public static void Main()
    {
        MyTreeView tree = new MyTreeView();
        tree.Drag();
        tree.Drop();
        tree.Serialize();
    }

 

 

 

 

 

Advertisements
This entry was posted in C#. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s