2012-01-20 13 views
15

В Java можно расширить интерфейс с помощью анонимного класса, который можно реализовать «на лету». Пример:C# анонимный интерфейс реализации (или абстрактный класс)

Runnable myRunnable = new Runnable() 
{ 
    @Override 
    public void run() { /**/ } 
} 

(Более подробно о: http://www.techartifact.com/blogs/2009/08/anonymous-classes-in-java.html#ixzz1k07mVIeO)

Возможно ли это в C#? Если нет, то какие жизнеспособные альтернативы не должны полагаться на реализацию множества подклассов?

ответ

14

Нет, вы не можете сделать это в C# - но обычно альтернативный подход к дизайну заключается в использовании делегата. В примере, вы дали, Runnable обычно представлены с использованием ThreadStart, и вы можете использовать анонимный метод или лямбда-выражение:

ThreadStart start =() => 
{ 
    // Do stuff here 
}; 

Или, если у вас есть только метод для запуска, с правом подписи, вы можете использовать преобразование метод группы:

ThreadStart start = MethodToRunInThread; 

Или в вызове конструктора Thread:

Thread t = new Thread(MethodToRunInThread); 
t.Start(); 

Если вы действительно необходимо реализовать интерфейс, вам нужно будет его реализовать (возможно, в частном вложенном классе). Тем не менее, это не очень часто случается на C#, по моему опыту - обычно интерфейсы C# - это такие, которые, естественно, потребуют «реальной» реализации, даже в Java.

+1

Это функция, которую я пропускаю время от времени, особенно потому, что мои интерфейсы часто узкие (интерфейсы роли) и придерживаются принципа разделения интерфейса. Было бы удобно, когда я мог бы зарегистрировать делегата в моей конфигурации DI, в то время как остальная часть приложения все равно могла бы зависеть от этого интерфейса (вместо «Func »), не создавая своего рода прокси-класс, который обертывает этот делегат и реализовать этот интерфейс. – Steven

6

Как указал Джон, это невозможно в C#.

Один альтернативный шаблон в C#, однако, должен использовать комбинацию фабрики и делегата, чтобы позволить на практике реализовать интерфейс. По сути, фабрика принимает делегата для каждого метода интерфейса и использует их в качестве поддержки. Например, вот версия для IComparable<T>.

public static class ComparableFactory { 
    private sealed ComparableImpl<T> : IComparable<T> { 
    internal Func<T, T, int> _compareFunc; 
    public int Compare(T left, T right) { 
     return _compareFunc(left, right); 
    } 
    } 
    public IComparable<T> Create<T>(Func<T, T, int> compareFunc) { 
    return new ComparableImpl<T>() { _compareFunc = compareFunc }; 
    } 
} 

... 

IComparable<Person> impl = CompareableFactory.Create<Person>(
    (left, right) => left.Age.CompareTo(right.Age)); 
+0

Очень круто, +1! Но, как хорошая практика, лучше просто перевернуть названный класс .. – nawfal

Смежные вопросы