В настоящее время мы обсуждаем, являются ли методы расширения в .NET плохими или нет. Или при каких обстоятельствах методы расширения могут вводить трудно найти ошибки или каким-либо другим образом ведут себя неожиданно.
Мы придумали:
- Написание метода расширения для типов, которые не находятся под вашим контролем (например, расширение DirectoryInfo с помощью GetTotalSize() и т.д.), является плохим, поскольку владелец API может ввести метод, который скрывает наше расширение - и может иметь разные граничные случаи. Например, тестирование для null в методе расширения автоматически преобразуется в исключение NullReferenceException, если метод расширения больше не используется из-за скрытия.
Вопрос:
- Есть ли какие-либо другие опасные ситуации, кроме "скрытия", о которых мы не думаем?
Edit:
Другая очень опасная ситуация. Предположим, что у вас есть метод расширения:
namespace Example.ExtensionMethods
{
public static class Extension
{
public static int Conflict(this TestMe obj)
{
return -1;
}
}
}
И используйте его:
namespace Example.ExtensionMethods.Conflict.Test
{
[TestFixture]
public class ConflictExtensionTest
{
[Test]
public void ConflictTest()
{
TestMe me = new TestMe();
int result = me.Conflict();
Assert.That(result, Is.EqualTo(-1));
}
}
}
Обратите внимание, что пространство имен, в котором вы его используете, длиннее.
Теперь вы ссылаетесь на dll с этим:
namespace Example.ExtensionMethods.Conflict
{
public static class ConflictExtension
{
public static int Conflict(this TestMe obj)
{
return 1;
}
}
}
И ваш тест не сработает! Он будет компилироваться без ошибки компилятора. Он будет просто терпеть неудачу. Без необходимости указывать "using Example.ExtensionMethods.Conflict". Компилятор будет проецировать имя пространства имен и найти Example.ExtensionMethods.Conflict.ConflictExtension перед Example.ExtensionMethods.Extension и будет использовать этот , не жалуясь на неоднозначные методы расширения. О, ужас!