我有一堆带有自动属性的商务类:
public class A {
public int Id { get; set; }
public string Title { get; set;}
}
由于应用程序不断发展,因此有一项新的要求是启用跟踪属性的更改,以便仅将更改的数据发送到后备存储。
为了达到这个目标,我必须将所有属性转换为字段+属性,如下所示:
public class A {
private int m_Id;
public int Id {
get { return m_Id; }
set {
if(m_Id != value){
SetChanged("Id");
m_Id = value;
}
}
}
private string m_Title;
public string Title
{
get { return m_Title; }
set {
if(m_Title != value){
SetChanged("Title");
m_Title = value;
}
}
}
protecte void SetChanged(string propertyName) {
// Not important here
}
}
有没有办法快速重构我的代码以避免手动更改属性?
IDE 中没有办法执行此操作,但是如果您需要替换所有 X 属性,我会编写一个简短的控制台应用程序来执行此操作。
该过程将是:
- 遍历目录匹配中的所有文件 *.cs
- 对于每个文件,正则表达式查找并替换旧属性以获取新属性语法
使用正则表达式进行匹配非常强大。正则表达式可以在VS2010中用于执行查找/替换操作。如果您尝试找到它(启用正则表达式)
{(public|private|internal|protected)}:b{[a-zA-Z0-9]+}
:b{[a-zA-Z0-9]+}:b{ get; set; }
它将匹配这样的属性
public Type Foo { get; set; }
在控制台应用程序中,找到与上述匹配的所有代码行,然后开始将它们拆分为修饰符、类型、属性名称,最后用类似这样的东西替换整个块
// PS: this is pseudocode ;-) or could be your new property template
private [Type] m_[PropertyName].ToPascaleCase
public [Type] PropertyName
{
get { return m_[PropertyName].ToPascaleCase; }
set
{
if(m_[PropertyName].ToPascaleCase != value){
SetChanged([PropertyName]);
m_[PropertyName].ToPascaleCase = value;
}
}
}
最后,我建议备份您的代码或离线运行此测试并在签入之前进行测试!!
您始终可以只创建一个泛型方法,该方法将执行赋值并调用SetChange
void SetChangeIfNeeded<T>(ref T field, T value, string propertyName)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
SetChanged(property);
}
}
您仍然需要有一个私人后场。 您的类将如下所示:
public class A {
private int m_id
public int Id
{
get { return m_id };
set { SetChangeIfNeeded<int>(ref m_id, value, "Id"); }
}
}
ReSharper 可以做到这一点,但不会修改 setter。
public string Title {
get { return m_title; }
set { m_title = value; }
}
可能没有直接的方法可以通过折射来做到这一点。如果这是我的问题。我会编写代码来生成这个:
public string MakePropertyBigger(string varName, string propName, string dataType)
{
string output = "";
output += string.Format("private {0} {1};", dataType, varName) + Environment.NewLine;
output += string.Format("public {0} {1}", dataType, propName) + Environment.NewLine;
output += "{" + Environment.NewLine;
output += string.Format("get { return {0}; }", varName) + Environment.NewLine;
output += string.Format("set { if({0} != value){ SetChanged("{1}");", varName, propName) + Environment.NewLine;
output += string.Format("{0} = value; }", varName) + Environment.NewLine;
output + "}" + Environment.NewLine + "}";
现在只需将其插入并取出即可。