Как я могу использовать расширение для добавления соответствия интерфейса к типу, который находится вне моего контроля?

На странице расширений документации Beef сказано следующее:

Расширения могут быть полезны для добавления соответствия интерфейса к типам, которые находятся вне вашего контроля (например, к системным типам или типам, определенным в другой библиотеке).

К сожалению, здесь нет примера такого варианта использования, и я не знаю, как действовать дальше.

Допустим, у меня есть интерфейс IFooBarable:

interface IFooBarable
{
    void FooBar();
} 

И я бы хотел добавить этот метод расширения к типу системной библиотеки System.DateTime:

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

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

... так что DateTime может реализовать IFooBarable.

Должен ли быть способ сказать компилятору обрабатывать DateTime как реализация IFooBarable? Например, такой, что это компилирует:

using System;

interface IFooBarable
{
    void FooBar();
}

/* extension code here */

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

            t.FooBar();
        }
    }
}

1 ответ

Решение

Оказывается, это так же просто, как использовать тот же синтаксис, который указывает на реализацию в объявлении класса. То есть все, что вам нужно сделать выше, это использовать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();
        }
    }
}

Вы даже можете сделать это, чтобы зарегистрировать метод, который уже есть в классе, как реализацию метода интерфейса с тем же именем, не имея ничего внутри 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);
        }
    }
}
Другие вопросы по тегам