Определение моего собственного метода Где для LINQ to Objects - Как узнать, какой из них будет использоваться? - PullRequest
1 голос
/ 30 сентября 2010

Просто для целей тестирования я определил свой собственный метод Where-Method для Linq следующим образом:

namespace Test
{
    public static class LinqTest
    {
        public static IEnumerable<TSource> Where<TSource>(
                        this IEnumerable<TSource> source,
                        Func<TSource, bool> predicate)
        {
            return new List<TSource> { };
        }
    }
}

Поэтому, если я использую такой запрос, я никогда не получу результат:

    var test = new string[]{ "a", "b", "c" };
    var x = from y in test
            where y.Length > 0
            select y;
    foreach (var element in x)
        Console.WriteLine(element);

Мой вопрос: как компилятор узнает, какой метод расширения должен быть вызван?Тот, который включен в LINQ, или пользовательский?

Cheers, Chris

Ответы [ 2 ]

3 голосов
/ 30 сентября 2010

Правила для метода расширения аналогичны правилам для обычного поиска вызова метода. Краткая версия - это то, что компилятор найдет все методы и методы расширения, какие из названий доступны, и выберет наиболее подходящее из них (методы без расширения предпочтительнее методов расширения).

Как и обычные методы, выбор метода расширения может быть неоднозначным. Это было бы здесь, если бы в приложении использовались пространства имен System.Linq и Test. Судя по вашей информации, кажется, что на пространство имен теста не указана using, следовательно, оно не будет рассматриваться, и версия Linq победит.

Примечание: Выше приведено краткое описание того, как происходит поиск, и оно ни в коем случае не является окончательным. Спецификация языка C # является здесь авторитетной и описывает ее гораздо подробнее.

1 голос
/ 30 сентября 2010

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

...