Home » Advanced CSharp » Two Interfaces. Same Method. Two meanings.

Two Interfaces. Same Method. Two meanings.

ppl-act-010 We’ve discussed interfaces before, but today I want to dig a little deeper.  I’m going to assume for now that you already know what an interface is and that you know how to implement one on a class.

But let’s assume for a bit that you have two interfaces that have exactly the same method declared in them but each implementation of the method has two entirely different meanings.  How do you code for this?

To make the question more concrete, let’s use a classic illustration.

Let’s assume that you have a Metric interface and an English interface and that each interface has a property called Height.  When you implement Metric on your class (Person), Height should return a Metric value.  When you implement English on your Person class, it should return the value in feet.  The English unit.

Obviously, you can’t implement this on the same method.  So what do you do?

You use the handles syntax.

Well, actually, there isn’t a handles keyword.  But that’s how the VB.NET guys handle it.  In CSharp, we have a syntax that says, “Don’t override the method with this name, instead make this method override that method.”  It’s actually pretty cool once you see it.

So, let’s set up our code.

First, our two interfaces:

public interface Metric
{
    int Height {get;set;}
}

public interface English
{
    int Height {get;set;}
}

and next our class:

public class Person : English, Metric
{
}

To implement a property Height that implements the English interface:

public class Person : English, Metric
{
    int m_englishHeight;
    int m_metricHeight;
    int English.Height
    {
        get{return m_englishHeight;}
        set{m_englishHeight = value;}
    }

    int Metric.Height
    {
        get { return m_metricHeight; }
        set { m_metricHeight = value; }
    }
}

And now, the code to create a person object and call the English or Metric Height:

Person p = new Person();
int englishHeight = ((English)p).Height;
int metricHeight = ((Metric)p).Height;

You’ll see that you must cast your Person object to either an English type or a Metric type before retrieving (or setting) height so that the runtime knows which method you want to call.  In fact, you can’t call English.Height or Metric.Height directly.  Try it.  It won’t even show up in intellisense.

If you want to have a default Height method on the Person class that returns the English unit, for example, you’d need to add another property, Height, to the Person class.

public int Height
{
    get { return ((English)this).Height; }
    set { ((English)this).Height = value; }
}

Which could be called like this:

int defaultHeight = p.Height;

So the full implementation of Person looks like this:

public class Person : English, Metric
{
    int m_englishHeight;
    int m_metricHeight;
    public int Height
    {
        get { return ((English)this).Height; }
        set { ((English)this).Height = value; }
    }

    int English.Height
    {
        get{return m_englishHeight;}
        set{m_englishHeight = value;}
    }

    int Metric.Height
    {
        get { return m_metricHeight; }
        set { m_metricHeight = value; }
    }
}

 

Other post in Advanced CSharp

Related Post

  • Using Sealed in CSharpUsing Sealed in CSharp Another potentially useful but not very popular keyword in CSharp is the sealed keyword.  While not a keyword that you will need to use often, it is a critical keyword for framework […]
  • Two Interfaces, One Method, Two Meanings (VB)Two Interfaces, One Method, Two Meanings (VB) Last week I showed how to implement two interfaces with one method and two meanings in CSharp.  One of the first comments I received for this post was, "How does this work in […]
  • What is the global keyword in CSharp?What is the global keyword in CSharp? During the Christmas break, I received the following question:What does C# global keyword actually do? Code example, from table adapter […]
  • Readonly variables in CSharp? Really?!Readonly variables in CSharp? Really?! I'm sure most of you are familiar with the keyword "const," which allows you to declare a variable and give it a value and assures that no other code will change the value. const int v = […]
  • Object Initialization in CSharp 3.0 and VB.NET 9Object Initialization in CSharp 3.0 and VB.NET 9 Yesterday we looked at the new var keyword in CSharp.  This makes CSharp variable declaration similar to VB.  After all, they've had the DIM keyword for years which essentially does the […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer. His commitment to quality through test driven development, vast knowledge of C#, HTML, CSS and JavaScript as well as his ability to mentor younger programmers and his passion for Agile/Scrum as defined by the Agile Manifesto and the Scrum Alliance will certainly be an asset to your organization.

  • Tom

    Interesting! Do you also happen to have the vb.net code for this?

  • Dave

    Come back next Monday

  • Terry

    Very Nice!

    You could use this site to convert it:

    http://www.developerfusion.com/tools/convert/csharp-to-vb/

  • Dave

    You could.. but then you wouldn’t learn much.

  • Terry

    Very True! I do use it sometimes, but I make sure I understand what it did to convert it.

    It’s just easier for me to follow VB.NET, since that is what I focus my efforts on.

  • http://developercontainer.blogspot.com ramil joaquin

    Very clear explanation. Thanks so much!