分部类和方法的学习【鸡蛋】

来源:互联网 发布:北京房产交易数据对比 编辑:程序博客网 时间:2024/05/01 10:38

     可以将类、结构或接口的定义拆分到两个或多个源文件中。每个源文件包含类定义的一部分,编译应用程序时将把所有部分组合起来。在以下几种情况下需要拆分类定义:

    1、处理大型项目时,使一个类分布于多个独立文件中可以让多位程序员同时对该类进行处理。

    2、使用自动生成的源时,无需重新创建源文件便可将代码添加到类中。Visual Studio 在创建 Windows 窗体、Web 服务包装代码等时都使用此方法。您无需编辑 Visual Studio 所创建的文件,便可创建使用这些类的代码。

    若要拆分类定义,请使用 partial 关键字修饰符,如下所示:
    public partial class Employee
    {
        public void DoWork()
        {
        }
    }

    public partial class Employee
    {
        public void GoToLunch()
        {
        }
    }

      使用 partial 关键字表明可在命名空间内定义该类、结构或接口的其他部分。所有部分都必须使用partial 关键字。在编译时,各个部分都必须可用来形成最终的类型。各个部分必须具有相同的可访问性,如 public、private 等。

   如果将任意部分声明为抽象的,则整个类型都被视为抽象的。如果将任意部分声明为密封的,则整个类型都被视为密封的。如果任意部分声明基类型,则整个类型都将继承该类。

指定基类的所有部分必须一致,但忽略基类的部分仍继承该基类型。各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。最终类型是所有部分在编译时的组合。

限制

处理分部类定义时需遵循下面的几个规则:

(1)要作为同一类型的各个部分的所有分部类型定义都必须使用 partial 进行修饰      public partial class A { }

(2)partial 修饰符只能出现在紧靠关键字 class、 struct 或 interface 前面的位置。

(3)分部类型定义中允许使用嵌套的分部类型,如下面的示例中所示:

    partial class ClassWithNestedClass
    {
        
partial class NestedClass { }
    }
    
    
partial class ClassWithNestedClass
    {
        
partial class NestedClass { }
    }

  

通过以上的文章分析,我们可以通过LINQ实例查看一下实际使用效果,

1.       新建立一个vs项目

2.       新建立一个dbml文件

3.       从服务器资源管理器重拉一个表到dbml文件中

Vs2010 自动为我们生成了DataClasses1DataContext.designer.cs类

 

internal partial class DataClasses1DataContext : System.Data.Linq.DataContext
{
...
}

这里留意internal partial class DataClasses1DataContext 使用了限制分部类的定义partial

出现的位置在class之前.

我们使用自动生成的源文件,我们不想修改vs创建的文件,于是我们可以建立一个分部类.新建立一个类进行扩展.

partial class DataClasses1DataContext

    {

    }

或者是dbml 里面的定义类

partial class Files
    {
        String  _myfiel;
        
public  string  myfilet
        {
            
get { return  _myfile; }
            
set { _myfile = value; }
        }
    }

分部方法

分部类或结构可以包含分部方法。类的一个部分包含方法的签名。可以在同一部分或另一个部分中定义可选实现。如果未提供该实现,则会在编译时移除方法以及对方法的所有调用。

分部方法使类的某个部分的实施者能够定义方法(类似于事件)。类的另一部分的实施者可以决定是否实现该方法。如果未实现该方法,编译器将移除方法签名以及对该方法的所有调用。因此,分部类中的任何代码都可以随意地使用分部方法,即使未提供实现也是如此。如果调用了未实现的方法,将不会导致编译时错误或运行时错误。

在自定义生成的代码时,分部方法特别有用。这些方法允许保留方法名称和签名,因此生成的代码可以调用方法,而开发人员可以决定是否实现方法。与分部类非常类似,分部方法使代码生成器创建的代码和开发人员创建的代码能够协同工作,而不会产生运行时开销。

分部方法声明由两个部分组成:定义和实现。它们可以位于分部类的不同部分中,也可以位于同一部分中。如果不存在实现声明,则编译器将优化定义声明和对方法的所有调用

// Definition in file1.cs
partial void onNameChanged();

// Implementation in file2.cs
partial void onNameChanged()
{
  
// method body
}

·         分部方法声明必须以上下文关键字 partial 开头,并且方法必须返回 void。

·         分部方法可以有 ref 参数,但不能有 out 参数。

·         分部方法为隐式 private 方法,因此不能为 virtual 方法。

·         分部方法不能为 extern 方法,因为主体的存在确定了方法是在定义还是在实现。

·         分部方法可以有 static 和 unsafe 修饰符。

·         分部方法可以为泛型的。约束将放在定义分部方法声明上,但也可以选择重复放在实现声明上。参数和类型参数名称在实现声明和定义声明中不必相同。

您可以为已定义并实现的分部方法生成 委托,但不能为已经定义但未实现的分部方法生成委托。

 

在LINQ使用中DataClasses1DataContext.dbml 文件自动为我们生成了DataClasses1DataContext.designer.cs类同时,还生成了一些可扩展性方法定义

例如

partial void OnLoaded();

partial void OnValidate(System.Data.Linq.ChangeAction action);

…..

方便开发人员可以决定使用该方法.



另外一个帖子:

我们知道LINQ中的增删改都要调用SubmitChanges方法,我们记录所有SQL的方式就是重写(override)DataContext中的SubmitChanges方法,为了避免每次修改dbml文件时影响我们自己写的内容,我们要先写一个DataContext的分布类,在这个类中重写SubmitChanges方法。
代码如下
Code

public partial class DataClasses1DataContext    {        public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)        {            //记录日志(每天一个文件,记录所有更改sql,日志会存在第一个盘的log文件夹下)            string directory = Path.Combine(Directory.GetLogicalDrives().First(), "log");            Directory.CreateDirectory(directory);            string logFile = Path.Combine(directory,                "log" + DateTime.Now.ToLongDateString() + ".txt");            using (StreamWriter w = File.AppendText(logFile))            {                               w.WriteLine("发生时间:{0}", DateTime.Now.ToString());                w.WriteLine("日志内容为:");                this.Log = w;                try                {                    base.SubmitChanges(failureMode);                }                catch (Exception e)                {                    w.WriteLine("异常:" + e.Message + e.StackTrace);                    w.WriteLine("--------------------------------------------------------------");                    throw;                }                finally                {                    this.Log = null;                }                w.WriteLine("--------------------------------------------------------------");            }        }    }转自:http://www.189works.com/article-43451-1.html

原创粉丝点击