5

我有一堆带有自动属性的商务舱:

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
    }
}

有没有办法快速重构我的代码以避免手动更改属性?

4

4 回答 4

3

在 IDE 中没有办法做到这一点,但如果您需要替换所有 X 属性,我会编写一个简短的控制台应用程序来做到这一点。

该过程将是:

  • 遍历目录中匹配 *.cs 的所有文件
  • Foreach 文件,正则表达式查找并替换旧属性以获得新属性语法

使用正则表达式进行匹配非常强大。正则表达式可以在 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;
        }
    }
}

最后,我建议您备份您的代码或离线运行此测试并在签入前进行测试!

于 2012-07-05T15:48:09.177 回答
1

您始终可以创建一个通用方法来执行分配和调用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"); }
    }  
}  
于 2012-07-05T15:45:15.023 回答
0

ReSharper 可以做到这一点,但不会修改 setter。

public string Title {
    get { return m_title; }
    set { m_title = value; }
}
于 2012-07-05T15:40:28.247 回答
0

折射可能没有直接的方法。如果这是我的问题。我会编写代码来生成这个:

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 + "}";

现在只需将其插入并拔出即可。

于 2012-07-05T15:51:57.863 回答