当前位置: 代码迷 >> 综合 >> C# 经典实例 第一章 类和泛型 #1.14 向生成的实体中添加钩子
  详细解决方案

C# 经典实例 第一章 类和泛型 #1.14 向生成的实体中添加钩子

热度:78   发布时间:2024-02-20 02:29:45.0

问题:

你有一种生成分部类业务实体定义的过程,并且想添加一种轻量级的通知机制。

解决方案:

使用分部方法在生成的代码中为业务实体添加钩子。

生成实体的过程可能来自于UML、数据集或者其他对象建模工具,但是当代码被生成为分部类时,为调用ChangingProperty 分部方法的属性会将分部方法挂钩添加到模板中,如

GeneratedEntity 类中所示。

public partial class GeneratedEntity
{public GeneratedEntity(string entityName){this.EntityName = entityName;}partial void ChangingProperty(string name, string originalValue,string newValue);public string EntityName { get; }private string _FirstName;public string FirstName{get { return _FirstName; }set{ChangingProperty("FirstName", _FirstName, value);_FirstName = value;}}private string _State;public string State{get { return _State; }set{ChangingProperty("State", _State, value);_State = value;}}
}

GeneratedEntity 具有两个属性:FirstName 和State。注意其中每个属性都具有相同的样板代码,它使用属性的名称、原始值和新值调用ChangingProperty 方法。如果此时使用生成的类,编译器将删除ChangingProperty 的声明和方法,因为不存在ChangingProperty 的实现。如果像下面这样提供一个实现来报告属性变化,那么将保留并执行ChangingProperty的所有分部方法代码:

public partial class GeneratedEntity
{partial void ChangingProperty(string name, string originalValue,string newValue){Console.WriteLine($"Changed property ({name}) for entity " +$"{this.EntityName} from " +$"{originalValue} to {newValue}");}
}

讨论:

在使用分部方法时,要注意以下几点。

用partial 修饰符指示分部方法。

只能在分部类中声明分部方法。

分部方法可以只有方法声明,而没有方法体。

从签名角度讲,分部方法可以包含参数,需要空返回值,不能有任何访问修饰符。分部意味着它是私有方法,并且可以是静态、泛型或者不安全的。

对于泛型分部方法,约束条件必须在声明和实现上重复标记。

分部方法不能实现接口成员,因为接口成员必须是公共的。

不能使用virtual、abstract、override、new、sealed 或extern 这些修饰符。

分部方法的参数不能使用out,但可以使用ref。

分部方法类似于条件方法,只不过条件方法中总会包含方法定义,甚至当条件未满足时也是如此。如果没有匹配的实现,分部方法将不会保留方法定义。可以像下面这样使用1.14.2 节中的代码。

public static void TestPartialMethods()
{Console.WriteLine("Start entity work");GeneratedEntity entity = new GeneratedEntity("FirstEntity");entity.FirstName = "Bob";entity.State = "NH";GeneratedEntity secondEntity = new GeneratedEntity("SecondEntity");entity.FirstName = "Jay";secondEntity.FirstName = "Steve";secondEntity.State = "MA";entity.FirstName = "Barry";secondEntity.State = "WA";secondEntity.FirstName = "Matt";Console.WriteLine("End entity work");
}

在提供了ChangingProperty 的实现时,将产生以下输出。

Start entity work  
Changed property (FirstName) for entity FirstEntity from to Bob  
Changed property (State) for entity FirstEntity from to NH  
Changed property (FirstName) for entity FirstEntity from Bob to Jay  
Changed property (FirstName) for entity SecondEntity from to Steve  
Changed property (State) for entity SecondEntity from to MA  
Changed property (FirstName) for entity FirstEntity from Jay to Barry  
Changed property (State) for entity SecondEntity from MA to WA  
Changed property (FirstName) for entity SecondEntity from Steve to Matt  
End entity work 

在没有提供ChangingProperty 的实现时,将产生以下输出。

Start entity work  
End entity work 

参考:

MSDN 文档中的“分部方法”和“分部(方法)”主题。

  相关解决方案