2016-07-12 3 views
3

У меня есть два метода расширения для интерфейса, который выполняет действие над экземпляром класса, реализующего интерфейс, и один в коллекции классов, реализующих интерфейс. Проблема в том, что компилятор всегда использует первый метод расширения, и это создает ошибку компиляции, поэтому я не могу использовать версию коллекции.Метод расширения Collision

public interface ISomeInterface 
{ 
} 

public class SomeClass : ISomeInterface 
{ 
} 

public static class SomeClassExtensions 
{ 
    public static T DoSomething<T>(this T item) where T : class, ISomeInterface 
    { 
     return item; 
    } 

    public static IEnumerable<T> DoSomething<T>(this IEnumerable<T> items) where T : class, ISomeInterface 
    { 
     return items; 
    } 
} 

internal class Program 
{ 
    private static void Main() 
    { 
     var items = new[] 
     { 
      new SomeClass() 
     }; 

     items.DoSomething(); // compiler error 
    } 
} 

Ошибка ясно, что компилятор пытается использовать первый метод расширения:

Типа «ConsoleApplication1.SomeClass []» не может быть использована в качестве параметра типа «T» в родовом тип или метод «SomeClassExtensions.DoSomething (T)». Нет никакого неявного преобразования ссылок из 'ConsoleApplication1.SomeClass []' в 'ConsoleApplication1.ISomeInterface'.

Очевидно, что я могу переименовать один из двух методов расширения, но это последнее средство, поскольку это для проекта с открытым исходным кодом, и я стараюсь избежать отклонения от установленного набора соглашений об именах.

У меня нет идей о том, как заставить то, что мне нужно для работы, возможно, есть способ добавить или скорректировать ограничения общего типа?

+0

@fubo Вы правы, опечатка исправлена. –

+0

Необходим ли ограничение 'class'? Если нет, вы можете сделать первое расширение не общим и сделать 'item' непосредственно типа' ISomeInterface'. –

+0

Часть метода расширения несущественна, но см. [Дубликат] (http://stackoverflow.com/questions/26037469/overload-resolution-issue-for-generic-method-with-constraints). – CodeCaster

ответ

2

Это должно сделать это

var items = new[] 
{ 
    new SomeClass() 
}; 

items.DoSomething<SomeClass>(); 

Это, конечно, предполагающей items является SomeClass[].

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