我们目前正在讨论.NET 中的扩展方法是否不好。或者在什么情况下扩展方法可能会引入难以发现的错误或以任何其他方式出现意外行为。
我们想出了:
- 为不受您控制的类型编写扩展方法(例如,使用 GetTotalSize() 扩展 DirectoryInfo 等)是不好的,因为 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;
}
}
}
你的测试将会失败!它将编译而不会出现编译器错误。它会根本就失败了。您甚至不必指定“使用Example.ExtensionMethods.Conflict”。编译器将遍历命名空间名称并在Example.ExtensionMethods.Extension之前找到Example.ExtensionMethods.Conflict.ConflictExtension,并使用它从未抱怨不明确的扩展方法。哦,可怕!
一些好奇心:
- 可能会调用扩展方法
null
实例;这可能会令人困惑(但有时很有用)
- 如果他们有不同的意图,“隐藏”问题就会很严重
- 同样,您可能会从 2 个不同的命名空间获得具有相同名称的不同扩展方法;如果你只有one两个命名空间中,这可能会导致不一致的行为(取决于哪个)......
- ...但是如果有人添加一个similar(相同签名)代码使用的第二个命名空间中的扩展方法,它将在编译时中断(不明确)
(edit)当然,还有“Nullable<T>
/new()
" bomb (see here https://stackoverflow.com/questions/194484/whats-the-strangest-corner-case-youve-seen-in-c-or-net/194671#194671)...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)