How can I use an extension to add interface conformance to a type that is outside my control?

42 views Asked by At

On the extensions page of the Beef documentation, it says this:

Extensions can be useful for adding interface conformance to types that are outside your control (ie: system types or types defined in another library).

Unfortunately, it doesn't provide an example of that use case, and I don't know how to proceed.

Suppose I have an interface IFooBarable:

interface IFooBarable
{
    void FooBar();
} 

And I would like to add this extension method to the system library type System.DateTime:

namespace System
{
    extension DateTime
    {
        public void FooBar()
        {
            String s = scope .();
            ToLongTimeString(s);

            Console.WriteLine("This dateTime ({}) has FooBarred", s); 
        }
    }
}

... such that DateTime can implement IFooBarable.

Is there supposed to be a way one can tell the compiler to treat DateTime as an implementation of IFooBarable? For instance, such that this compiles:

using System;

interface IFooBarable
{
    void FooBar();
}

/* extension code here */

namespace Program
{
    public class Program
    {
        static void Main()
        {
            IFooBarable t = DateTime.Now;

            t.FooBar();
        }
    }
}
1

There are 1 answers

0
Ruzihm On BEST ANSWER

Turns out it's as easy as using the same syntax as what indicates implementation in a class declaration. That is to say, all you need to do above is use extension DateTime : IFooBarable:

using System;

interface IFooBarable
{
    void FooBar();
}

namespace System
{
    extension DateTime : IFooBarable
    {
        public void FooBar()
        {
            String s = scope .();
            ToLongTimeString(s);

            Console.WriteLine("This dateTime ({}) has FooBarred", s); 
        }
    }
}

namespace Program
{
    public class Program
    {
        static void Main()
        {
            IFooBarable t = DateTime.Now;

            t.FooBar();
        }
    }
}

You can even do this to register a method that a class already has as an implementation of an interface's method of the same name by not having anything inside the extension:

using System;

interface IFooBarable
{
    void ToLongTimeString();
}

namespace System
{
    extension DateTime : IFooBarable
    {
    }
}

namespace Program
{
    public class Program
    {
        static void Main()
        {
            IFooBarable t = DateTime.Now;

            String s = scope .(); 
            t.ToLongTimeString(s);

            Console.WriteLine("{}", s);
        }
    }
}