我有一个类是这样的类:
public class Abc
{
public string City
{
get { return _getValue(); }
set { _setValue(value); }
}
public string State
{
get { return _getValue(); }
set { _setValue(value); }
}
private string _getValue()
{
// determine return value via StackTrace and reflection
}
...
}
Run Code Online (Sandbox Code Playgroud)
(是的,我知道StackTrace /反射很慢;不要惹我生气)
鉴于所有属性都被声明为相同,我能够做的就是有一些简单/干净的方式来声明它们,而不需要反复复制相同的get/set代码.
我需要所有属性的Intellisense,这排除了使用例如.ExpandoObject.
如果我在C/C++的土地上,我可以使用一个宏,例如:
#define DEFPROP(name) \
public string name \
{ \
get { return _getValue(); } \
set { _setValue(value); } \
} \
Run Code Online (Sandbox Code Playgroud)
然后:
public class Abc
{
DEFPROP(City)
DEFPROP(State)
...
}
Run Code Online (Sandbox Code Playgroud)
但当然这是C#.
那么......任何聪明的想法?
####编辑###
我想我原来的帖子不够清楚.
我的帮助函数_getValue()根据调用的Property执行一些自定义查找和处理.它不仅存储/检索简单的特定于prop的值.
如果我需要的只是简单的值,那么我只使用自动属性
public string { get; set; }
Run Code Online (Sandbox Code Playgroud)
并完成它,并不会问这个问题.
首先:CallerMemberNameAttribute注入调用成员名称,因此不需要反射:
public class Abc
{
public string City
{
get { return _getValue(); }
set { _setValue(value); }
}
public string State
{
get { return _getValue(); }
set { _setValue(value); }
}
private string _getValue([CallerMemberName] string memberName = "")
{
}
private void _setValue(string value,
[CallerMemberName] string memberName = "")
{
}
}
Run Code Online (Sandbox Code Playgroud)
其次:通过利用.4文件生成的T4模板,可以实现类型成员的生成:
<#@ output extension=".cs" #>
<#
var properties = new[]
{
"City",
"State"
};
#>
using System.Runtime.CompilerServices;
namespace MyNamespace
{
public class Abc
{
<# foreach (var property in properties) { #>
public string <#= property #>
{
get { return _getValue(); }
set { _setValue(value); }
}
<# } #>
private string _getValue([CallerMemberName] string memberName = "") {}
private void _setValue(string value, [CallerMemberName] string memberName = "") {}
}
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以卸载_setValue和_getValue包含文件,以便为其他模板提供可重用性.
T4模板确实具有优于宏的优势,可以随时重新生成代码.因此,即使在初始生成之后,也可以应用对源代码的调整(可能是实现自适应或属性重命名).
有人弄清楚了如何在 c# 中使用 c 预处理器
但是:您应该避免使用堆栈跟踪来达到您的目的!!!!将字符串传递给 _getValue("name") 或自动生成字段。如果您使用堆栈跟踪,则必须停用方法内联(简单)以及尾部调用优化(不确定这是否可能)。
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |