我有以下结构,并希望解决方案同时受益于以下两个类.第一个类使用字符串和强类型成员:
public class UserSessionData
{
private string Get(string key)
{
throw new NotImplementedException("TODO: Get from external source");
}
private void Set(string key, string value)
{
throw new NotImplementedException("TODO: Set in external source");
}
public string CustomerNumber {
get { return Get("CustomerNumber"); }
set { Set("CustomerNumber", value); }
}
public string FirstName {
get { return Get("FirstName"); }
set { Set("FirstName", value); }
}
public string LastName {
get { return Get("LastName"); }
set { Set("LastName", value); }
}
// ... a couple of hundreds of these
}
Run Code Online (Sandbox Code Playgroud)
我可以想像一种替代是一个Get和Set方法用enum参数.这是第二堂课:
public class UserSessionData
{
public enum What {
CustomerNumber, FirstName, LastName, // ...
}
public string Get (What what) { return MyExternalSource(what); }
public string Set (What what, string value) { return MyExternalSource(what); }
}
Run Code Online (Sandbox Code Playgroud)
但是#2类的消费者方面并不漂亮:
UserSessionData.Get(UserSessionData.What.CustomerNumber)
将它与第一类比较:UserSessionData.CustomerNumber
在我的第一个类示例中是否有一种强类型的方法来调用Get和Set方法?换句话说:如何从两个类中获益,即强类型成员的可维护性和漂亮的语法?
lig*_*cko 34
如果你使用.Net 4.5或更新版本,你可以使用CallerMemberNameAttribute,这样就可以像这样调用它:
public string CustomerNumber {
get { return Get(); }
}
Run Code Online (Sandbox Code Playgroud)
要使其工作,请通过向参数添加属性来修改Get方法:
private string Get([CallerMemberName] string key)
{
...
}
Run Code Online (Sandbox Code Playgroud)
性能提示:编译器会在调用站点插入一个字符串作为参数,因此速度很快.
如果您使用.NET 4.0或更早版本,您仍然可以使用强类型属性名称,而不是手动输入的字符串,但你需要实现一个方法,像这样从一个提取属性的名称表达,然后你可以使用表达式叫它:
public string CustomerNumber {
get { return Get(() => this.CustomerNumber ); }
}
Run Code Online (Sandbox Code Playgroud)
设置器可以以相同的方式实现.
性能提示:字符串在运行时提取,因此比使用CallerMemberNameAttribute慢.
您可以使用T4模板生成类.在T4模板中,您只需命名所有属性 - 您也可以通过枚举的反射来获取它们,但使用字符串数组更简单.
添加新项目 - >文本模板
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<# var properties = new string [] {
"CustomerNumber", // This is where you define the properties
"FirstName",
"LastName"
}; #>
class UserSessionData {
<#
foreach (string propertyName in properties)
{ #>
public string <#= propertyName #>{
get { return Get("<#= propertyName #>"); }
set { Set("<#= propertyName #>", value); }
}
<# } #>
}
Run Code Online (Sandbox Code Playgroud)
更多信息@ 使用T4文本模板生成设计时代码