C# 中的部分类及实际示例






4.70/5 (61投票s)
我用一个例子来解释 C# 语言中的部分类。
引言
在本文中,我将通过一个示例来解释 C# 语言中的 partial
类。partial
类将一个类的定义分散到两个或多个源文件中。您可以创建在多个文件中定义的类,但它会被编译成一个类。
假设您有一个“Person
”类。该定义被分成两个源文件“Person1.cs”和“Person2.cs”。然后这两个文件就拥有了一个 partial
类。您编译源代码,然后会创建一个单一的类。让我们在图 1.1 中看看。
分部类的优点
以下是分部类的一些优点列表:
- 您可以将 UI 设计代码和业务逻辑代码分开,这样更容易阅读和理解。例如,您正在使用 Visual Studio 开发一个 Web 应用程序,并添加一个新的 Web 窗体,这时会有两个源文件,“aspx.cs”和“aspx.designer.cs”。这两个文件具有相同的类,并带有
partial
关键字。“.aspx.cs”类包含业务逻辑代码,而“aspx.designer.cs”包含用户界面控件的定义。 - 在使用自动生成源代码时,可以将代码添加到类中,而无需重新创建源文件。例如,您正在使用 LINQ to SQL 并创建一个 DBML 文件。现在,当您拖放表时,它会在 designer.cs 文件中创建一个
partial
类,并且所有表列在该类中都有属性。您需要在该表中添加更多列以绑定到 UI 网格,但您不想向数据库表中添加新列,因此您可以为该类创建一个单独的源文件,其中包含该列的新属性,它将成为一个分部类。这样就不会影响数据库表和 DBML 实体之间的映射,但您可以轻松获得一个额外的字段。这意味着您可以在不干扰系统生成代码的情况下编写自己的代码。 - 多名开发人员可以同时为同一个类编写代码。
- 通过压缩大型类,您可以更好地维护应用程序。假设您有一个具有多个接口的类,您可以根据接口实现创建多个源文件。这样就很容易理解和维护实现了哪个接口的源文件中的分部类。让我们看下面的代码片段。
public interface IRegister { //Register related function } public interface ILogin { //Login related function } //UserRegister.cs file public partial classUser : IRegister, ILogin { //implements IRegister interface } //UserLogin.cs file public partial classUser { //implements ILogin interface }
使用分部类时需要注意的点
在使用分部类开发应用程序时,有一些点需要您注意。
- 您需要在分部类的每个部分中使用
partial
关键字。 - 分部类的每个部分名称必须相同,但每个部分的源文件名可以不同。
- 分部类的所有部分都应位于同一命名空间中。
- 分部类的每个部分都应位于同一个程序集或 DLL 中,换句话说,您不能在不同类库项目的源文件中创建分部类。
- 分部类的每个部分具有相同的可访问性。
- 如果您继承一个类或接口到一个分部类,那么它将继承到分部类的所有部分。
- 如果分部类的一个部分被标记为
sealed
,那么整个类都将是sealed
的。 - 如果分部类的一个部分被标记为
abstract
,那么整个类将是abstract
类。
Using the Code
我将开发一个示例来解释如何在项目中使用了分部类。假设您在应用程序中使用了 LINQ to SQL。因此,您创建了一个数据上下文,换句话说,一个 .dbml 文件,然后拖放必要的表。每个表在数据上下文设计器文件中都会创建一个 partial
类,并且每个表字段都会成为该表的属性。假设您有一个“Person
”表,该表有三个字段“Id
”、“Name
”和“DateOfBirth
”,并且您想在网格视图中显示每个人的年龄。您该怎么做?如果您为“Person
”表在数据库中添加一个年龄的新列,那么这会违反范式化规则,所以不应该这样做。如果您向自动生成的代码添加一个新属性,那么它将不会映射到数据库。因此,您需要在一个单独的源文件中创建一个 partial
类部分,该部分具有“Age
”属性。这个“Age
”属性在您将 person
列表绑定到网格视图时计算人的年龄。让我们一步一步地看。
- 在数据库中创建一个“
Person
”表。您需要在数据库中创建一个
person
表,该表有三个字段“Id
”、“Name
”和“DateOfBirth
”。“Id
”字段是主键。CREATE TABLE Person ( Id int identity(1,1)primary key, Name nvarchar(50), DateOfBirthDate default getUtcDate() )
- 从 Visual Studio 创建一个 Web 应用程序。
- 在解决方案资源管理器中右键单击项目,然后转到“添加”,再单击“类”。
- 从列表中选择“LINQ to SQL 类”,然后为 DBML 名称提供“
Person
”。然后单击“添加”。 - 将数据库中的 User 表从服务器资源管理器拖放到“Person.dbml”文件的 O/R Designer 表面上。
图 1.2:Person 实体
现在您可以打开“Person.designer.cs”文件。在该文件中,已经为从数据库拖放到 O/RM 表面上的“
Person
”表创建了“Person
”分部类。 - 创建一个
partial
类部分,其中包含计算年龄的“Age
”属性。该文件名为“PersonExtension.cs”。using System; namespace PartialClassExample { public partial class Person { public int Age { get { return Convert.ToInt32(System.DateTime.UtcNow.Date.Year - _DateOfBirth.Value.Year); } } } }
- 创建一个 UI 设计,在网格视图中显示人的详细信息。
<%@Page Language="C#"AutoEventWireup="true" CodeBehind="PersonUI.aspx.cs"Inherits="PartialClassExample.PersonUI"%> <!DOCTYPEhtml> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head id="Head1"runat="server"> <title></title> </head> <body> <formid="form1"runat="server"> <div> <asp:GridViewID="gridPerson"runat="server"> </asp:GridView> </div> </form> </body> </html>
- 在代码隐藏文件中,编写“
Page_Load
”事件的代码,以便通过person
列表绑定网格视图。using System; using System.Linq; namespace PartialClassExample { public partial class PersonUI : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { using (PersonDataContext context =new PersonDataContext()) { var query = from person in context.GetTable
() select new { person.Id, person.Name, person.DateOfBirth, person.Age }; var content = query.ToList(); gridPerson.DataSource = content; gridPerson.DataBind(); } } } } - 运行应用程序,您将在网格视图中看到
Age
列,其中显示了每个人的年龄。让我们在图 1.3 中看看。图 1.3:输出