以我的理解,该partial
关键字什么也没有做,只是允许在几个源文件之间拆分一个类。除了代码组织之外,还有其他理由吗?我已经在生成的UI类中看到了它的用法。
似乎没有理由创建整个关键字。如果一个类足够大而需要多个文件,那么它可能做得太多。我以为您也许可以用它部分地定义一个类,供其他程序员在某个地方完成,但是最好创建一个抽象类。
以我的理解,该partial
关键字什么也没有做,只是允许在几个源文件之间拆分一个类。除了代码组织之外,还有其他理由吗?我已经在生成的UI类中看到了它的用法。
似乎没有理由创建整个关键字。如果一个类足够大而需要多个文件,那么它可能做得太多。我以为您也许可以用它部分地定义一个类,供其他程序员在某个地方完成,但是最好创建一个抽象类。
Answers:
在每种情况下某个自定义工具生成类的一部分的每种情况下,它都非常有用,因为它允许您在不继承生成的类的情况下向生成的代码添加自定义逻辑。顺便说一句。出于相同的原因,也有部分方法。
它不仅与UI有关,而且其他技术(如Linq-To-Sql或Entity Framework)也大量使用此功能。
如您所说,它通常用于分隔生成的代码。它通常与类/文件的大小无关。
分离生成的代码的好处是样式之一。生成的代码非常丑陋且不可读,并且会导致许多编码标准(以及StyleCop检查)无法通过,但这没关系,没有人必须阅读或直接维护它。因此,如果您将其“隐藏”在另一个文件中,则可以集中精力确保该类的其余部分符合标准,并通过StyleCop检查等等。
我用过的另一个地方是一个类实现多个接口,将实现分离到单独的文件中会很好,尽管这更多是个人喜好,我从未见过任何编码标准要求(或防止)。
我工作的一位开发人员在几周前提出了对他们很好的用处,以重构庞大的God类,这些类逐渐失去控制并具有许多公共方法:通过分离每部分的逻辑功能将该类划分为单独的部分类,您可以在不破坏任何现有功能的情况下,将类物理上划分为应该是该类的更多原子单元,从而使您可以看到什么是通用的,什么不是通用的。以此为第一步,您可以更轻松地将部分分解为各自的独立类,并在整个代码库中实现它们。我认为这是一个好主意。
但是,总的来说,我认为仅在编写新代码时才应使用它们来扩展机器生成的类。
我可以想到一些有用的场景,其中的局部是有意义的,其中大多数是我在项目中使用的自己:
将Tool / IDE / Designer生成的代码与您要维护的代码分开。一个很好的例子是该Form.Designer.cs
文件包含设计器为Windows窗体应用程序生成的代码。许多其他.NET格式还具有一些由工具生成的代码,可以在生成项目时重新生成这些代码,因此所有自定义更改都将被清除。分离将帮助您保持代码和更改免受此类自动修改的影响。
当您在实现中使用大量代码实现多个接口时。我倾向于使用一个单独的部分文件对于每个这样的接口,将其命名为这样的:{Class}.{Interface}.cs
。我很容易在IDE中看到{Class}
正在实现的接口和实现方式。
当类必须包含一个或多个嵌套类时,尤其是其中包含足够的代码才能放入单独的文件中时。我会坚持上述模式,并{Class}.{NestedClass}.cs
为每个嵌套类使用命名约定。Virtlink的答案已经提到了类似的做法。
当我编写static
将包含扩展方法的类时。通常会为相似的类或接口提供相同的扩展方法逻辑,例如Reverse
在通用和非通用集合上。我会将单个类或接口的所有扩展方法放在静态类的单独部分中。例如,我将IList
在一个位置具有该接口的所有扩展方法,而IList<T>
在另一文件中具有相同的方法。另一种方法是将相同的方法(其所有重载)放在相同的部分中,并为该this
参数提供所有可能的类,例如让所有Reverse
一个文件中的实现。它取决于哪一个可以更好地证明代码量或您或您的组织可能遵循的一些内部约定方面的合理性。
我不使用它,但是我看到一些C / C ++人士喜欢我将在这里描述的方法:仅使用局部方法为类创建局部。这类似于C / C ++的方法,用于定义接口并将方法声明与实现分开。
纯粹出于逻辑上的关注而分开。如果碰巧使用一个大型类,而大型类本身包含多个逻辑操作集,则可以将每个与逻辑相关的代码分成一个单独的部分。通常,此类的存在与关注点分离原则背道而驰,但通常会在现实生活中观察到这种情况,尤其是对于较旧的代码库。相同用户史蒂夫·埃弗斯(Steve Evers)在回答此问题时提到了它们,并以“ 上帝对象”的名字来称呼它们。我个人会使用部分类的方法在对如此大的文件进行任何重构之前对代码进行拆分,以简化我的工作并使重构更加透明。这也将减少涉及SVN等版本控制系统时可能引起的冲突。
我从未见过任何人提及它:我曾经partial
将嵌套类放在自己的文件中。
我所有的代码文件仅包含一个类,结构,接口或枚举。当文件名显示您要查找的对象的名称时,使查找对象的定义变得容易得多。并且由于Visual Studio尝试将项目文件夹与名称空间进行匹配,因此文件名应与类匹配。
这也意味着NestedClass
嵌套在其中的类MyClass
将在我的项目中拥有自己的文件:MyClass.NestedClass.cs
。
partial class MyClass
{
private class NestedClass
{
// ...
}
}
除了使用生成的代码外,我只见过它们被用来掩盖上帝的对象。试图理解一个新的代码库或浏览同一对象的多个源文件实在令人讨厌。
因此,当您问Why use partial classes?
我答案时:除非您使用的是生成的代码,否则不要这样做。
我可以想到它们的肮脏用途。
假设您有一些需要通用功能的类,但是您不想将该功能注入到它们之上的继承链中。或者,您有一组使用通用帮助程序类的类。
基本上,您想进行多重继承,但是C#不太可能。因此,您要做的是使用partial创建本质上在C / C ++中的#include。
将所有功能放在一个类中,或使用帮助程序类。然后将帮助程序复制X次,并将其重命名为A,B,C部分类。并将部分内容放在您的A,B,C类上。
免责声明:是的,这是邪恶的。永远不要这样做-特别是如果它会使其他人对您发怒。
partial
只有在出现时才有意义class
。您可以使用它作为代码等其他地区的标识符名称