如何重构这个?

时间:2011-04-13 18:45:21

标签: c# reflection code-snippets

我试图重构这个

class AClass
{
     string Property1 { get; set; }
     string Property2 { get; set; }
     string Property3 { get; set; }

     void AMethod(AClass other)
     {
         if(String.IsNullOrEmpty(this.Property1))
         {
              this.Property1 = other.Property1;
         }

         if(String.IsNullOrEmpty(this.Property2))
         {
              this.Property2 = other.Property2;
         }

         if(String.IsNullOrEmpty(this.Property3))
         {
              this.Property3 = other.Property3;
         }
     }
 }

我唯一可以提出的是

    private string GetFirstNotNullOrEmpty(string first, string second)
    {
        if (String.IsNullOrEmpty(first))
        {
            return second;
        }

        return first;
    }

    this.Property1 = GetFirstNotNullOrEmpty(this.Property1, other.Property1);

这不完全等同,但会完成这项工作。有没有更好的方法来重构这个?

6 个答案:

答案 0 :(得分:4)

如果要对该类的N个字符串属性执行此操作,则应使用Reflection实现该属性。

<强>更新

这都是关于“teh codez”的,对吗?在这里:

class SomeClass
{
    public string Property0 { get; set; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    public string Property3 { get; set; }
    public string Property4 { get; set; }
    public string Property5 { get; set; }
    public string Property6 { get; set; }
    public string Property7 { get; set; }
    public string Property8 { get; set; }
    public string Property9 { get; set; }

    public override string ToString()
    {
        //just to print out all properties and values
        foreach (PropertyInfo prop in typeof(SomeClass).GetProperties())
        {
            Console.WriteLine(prop.Name + "," + prop.PropertyType + " = " + prop.GetValue(this, null));
        }
        return base.ToString();
    }

    public void CopyStringPropertiesIfEmptyFrom(SomeClass SourceInstance)
    {
        foreach (PropertyInfo prop in typeof(SomeClass).GetProperties())
        {
            if (prop.PropertyType == typeof(System.String) && String.IsNullOrEmpty((string)prop.GetValue(this, null)))
            {
                prop.SetValue(this, prop.GetValue(SourceInstance, null), null);
            }
        }
    }

}

答案 1 :(得分:2)

您可以将ifs折叠为三元运算符,而不是使用方法:

this.Property1 = String.IsNullOrEmpty(this.Property1)? other.Property1 : this.Property1;

答案 2 :(得分:1)

在属性中实现检查。

public class AClass
{
    string Property1 
    { 
        get { return _Property1; }
        set
        {
            if (String.IsNullOrEmpty(_Property1))
            {
                _Property1 = value
            }
        }
    }
    private string _Property1;


    void AMethod(AClass other)
    {
        this.Property1 = other.Property1;// Property can only be set once.
    }

}

答案 3 :(得分:0)

当我可以避免使用Reflection时,我不喜欢使用Reflection,所以我实际上喜欢你在问题中建议的选项,但稍微混合了Tesserex的答案:

private string GetFirstNotNullOrEmpty(string first, string second)
{
    return String.IsNullOrEmpty(first)) ? second : first;
}

答案 4 :(得分:0)

我认为最好的解决方案就像

private void SetFirstNotNullOrEmpty(string first, string second, Action<T> setter)
{
    if (String.IsNullOrEmpty(first))
    {
        setter(second);
    }
}

它会像这样调用:

this.Property1 = GetFirstNotNullOrEmpty(this.Property1, other.Property1, i => this.Property1 = i);

如果那些不是C#属性,这将更好。使用公共字段,我可以传递引用,并将getter和setter都放在一个参数中。

答案 5 :(得分:0)

这里需要重构的第一件事是非直观的名称,如Property1和AClass。为类和属性名称使用有意义的名称,以便它们清楚地反映意图。

或许,OP希望我们专注于手头的问题而不是这方面。