Defining implicit and explicit casts for C# interfaces

You cannot define casts or operator overloading on interfaces. Since an interface is a contract that describes the members which will always be available (either as an explicit cast to that interface or as public members) and nothing more you cannot rely on interfaces to contain any sort of built in logic such as how to cast or how operators will perform with that interface.

You can still inherit from an abstract base class which implements the interface and provides the logic you need for casts or operator overloading. This doesn't violate interface oriented design. Classes which do not inherit from the common base class but implement the interface will still need to independently implement their own implicit casts and operator overloads. If you wish to centralize the logic for working with classes that commonly implement an interface you can do so in C# 3.0+/.NET Fx 3.5 with extension methods (or in previous versions with static methods). Below I demonstrate this with a utility class and two classes, Foo and Bar, which don't have a common ancestor. They share the code which comprises the utility function Add so you don't have to repeat this implementation in both classes.

public interface IInterface
{
    int X { get; set; }
    int Y { get; set; }
}

public static class IInterfaceTHelper
{
    public static IInterface Add<T>(this IInterface a, IInterface b) 
        where T : new()
    {
        var ret = (IInterface)new T();
        ret.X = a.X + b.X;
        ret.Y = a.Y + b.Y;
        return ret;
    }
}

class Foo : IInterface
{
    public int X { get; set; }
    public int Y { get; set; }

    public static IInterface operator +(Foo a, IInterface b)
    {
        return a.Add<Foo>(b);
    }
}

class Bar : IInterface
{
    public int X { get; set; }
    public int Y { get; set; }

    public static IInterface operator +(Bar a, IInterface b)
    {
        return a.Add<Bar>(b);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo { X = 5, Y = 3 };
        var bar = new Bar { X = 3, Y = 5 };

        var result = foo + bar;
        Console.WriteLine(result.GetType().Name + " " + result.X + " " + result.Y);
        result = bar + foo;
        Console.WriteLine(result.GetType().Name + " " + result.X + " " + result.Y);

        Console.ReadLine();
    }
}

If your interfaces contained more than just contracts that would be violating design by contract.


One way to do this is if there is a cast/conversion you'll often need is to define an explicit method on your interface e.g.

public interface ISomeInterface
{
   TargetType ToTargetType();
}

Then in an abstract base class you can define an implicit/explicit cast and have the cast operator just call the interface method in which you define your actual cast logic e.g.

public abstract class SomeAbstractClass : ISomeInterface
{
  public TargetType ToTargetType()
  {
    // Actual cast logic goes here
    return (TargetType)this;
  }

  public static explicit operator TargetType(SomeAbstractClass obj)
  {
    return ToTargetType();
  }
}

This way you ensure that implementations provide a means to cast to the necessary type. Thus purely interface driven code can call the interface method to do the conversion. But your code that uses concrete implementations of the interface will have the cast operators defined and can use them instead

Tags:

C#

Interface