Как это изменить? - PullRequest
       19

Как это изменить?

4 голосов
/ 13 апреля 2011

Я пытался рефакторинг этого

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 ]

4 голосов
/ 13 апреля 2011

Если вы собираетесь сделать это для N строковых свойств этого класса, вы должны реализовать это, используя Отражение .

Обновление

Это все о "коде", верно?Вот так:

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

}
2 голосов
/ 13 апреля 2011

Вместо использования метода вы можете свернуть ifs в троичные операторы:

1 голос
/ 13 апреля 2011

реализовать проверку в самих свойствах.

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

}
0 голосов
/ 11 января 2015

Первое, что здесь нужно реорганизовать, - это неинтуитивные имена, такие как Property1 и AClass.Используйте значимые имена для имен классов и свойств, чтобы они четко отражали цель.

Возможно, ФП хочет, чтобы мы сосредоточились на проблеме, а не на этом аспекте.

0 голосов
/ 13 апреля 2011

Я думаю, что лучшим решением будет что-то вроде

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 #. С открытыми полями я мог бы передать ссылку и иметь и геттер и сеттер в одном параметре.

0 голосов
/ 13 апреля 2011

Я не фанат использования Reflection, когда я могу этого избежать, поэтому мне действительно нравится предложенный вами вариант в вопросе, но он слегка смешан с ответом Tesserex:

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