Методы расширения на IList и IEnumerable с тем же именем? - PullRequest
3 голосов
/ 04 января 2010

Я написал некоторые методы расширения для преобразования IEnumerable и IList в строку. Теперь, поскольку IList наследует от IEnumerable, я должен назвать их по-другому.

Мне просто интересно, есть ли способ избежать этого? Могу ли я иметь метод расширения для IEnumerable, а затем другой для IList с тем же именем и с той же подписью? Вроде как переопределение, за исключением того, что методы Extension конечно статические.

Я просто хотел бы использовать более эффективное тело метода в Списке, не имея второго имени метода.

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

Ответы [ 2 ]

5 голосов
/ 04 января 2010

Почему бы вам не сделать то, что делает BCL, и не попытаться выполнить снижение в том же методе?

Что-то вроде этого:

public static string Foo<T>(this IEnumerable<T> source)
{
    var list = source as IList<T>;
    if(list != null)
    {
        // use more efficient algorithm and return
    }
    // default to basic algorithm
}

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

4 голосов
/ 04 января 2010

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

По сути, вы инкапсулируете связанные методы внутри объекта и возвращаете экземпляр из метода расширения:

public interface ISecurity
{
    Permissions GetPermissions(Uri resource);
}

public static class SecurityExtensions
{
    public static ISecurity Security(this IPerson person)
    {
       return new SecurityImpl(person);
    }
}

Вы можете использовать эту технику для «пространства имен» ваших методов расширения.

...