我希望 .NET 框架中有一项特定功能,但事实并非如此。我希望有一个 DBDataReader.GetString(或 GetDateTime、GetInt32 等)重载接受字段名而不是索引。使用字段名称可以更轻松地维护 IMO,但 GetXxx 方法只接受字段位置。
我可以通过使用扩展方法将这些添加到我的项目中(至少以有限的能力满足我的即时需求),但感觉有些不对劲。除了我必须为每个新项目重复此过程这一明显问题之外,还有什么理由不做我正在考虑的事情吗?
例如,我是否在试图重写框架以适应我的突发奇想?我会让那个必须修改我的代码(可能是我)的可怜人摸不着头脑,试图弄清楚发生了什么吗?我是否违反了 OOP 的一些核心原则?
只是寻找指导和观点。谢谢。
请您参考如下方法:
这正是扩展方法能够解决的场景之一。您需要的功能在您无法控制的类型上尚不可用。
至于在每个项目中复制代码,您需要做的是创建一个类库项目来存储您的公共(public)/共享代码,然后在每个解决方案中包含该项目并使用项目引用或编译项目,将生成的程序集放在共享位置并将其作为文件项目引用包含在内。
请记住,扩展方法只有在“引入范围内”时才可用。这意味着如果您将扩展方法定义为:
namespace CustomExtensions
{
public static class StringExtensions
{
public static string InvariantToString(this int value)
{
return value.ToString(System.Globalization.CultureInfo.InvariantCulture);
}
}
}
它不会在任何字符串值上可见,除非代码文件包含带有 using 指令的 CustomExtensions 命名空间。
因此,建议您不要将自己的扩展放在 .NET Framework 定义的命名空间中,而是使用自己的命名空间。这样做可以最大限度地减少混淆的可能性,因为除非明确将其引入范围,否则您的扩展将不可用。
此外,请记住,如果您提供的扩展方法与“内置”方法具有完全相同的签名,您的扩展方法将永远不可见或可调用 - 内置方法 always 优先。如果 Microsoft 决定在更高版本的框架中包含该功能并使用您选择的完全相同的签名,那么您的扩展方法将不再被调用。
当您定义一个扩展方法时,您实际上并没有重新定义被扩展的基础类型,因此您没有自己的“个人版本”。扩展方法所提供的只是一种在静态类中调用静态方法的方便且更自然的方式。事实上,使用我上面的示例扩展方法,这些是等效的调用:
int i = 42;
Console.WriteLine(i.InvariantToString());
Console.WriteLine(StringExtensions.InvariantToString(i));
虽然 Microsoft 确实对框架中包含或不包含的内容进行了很多思考,但他们无法了解可能会驱动您对某些功能的特定需求的特定用例。是的,大多数时候他们做得很好并提供“开箱即用”的功能,但其他时候他们没有。 (一个很好的例子是缺少 InvariantToString() 方法。)