A more elegant way to update the properties of an empty object

I am currently writing a method that fills in the missing properties of an object. The object had some values ​​established from the database, but if they are empty, then it goes to an alternative data source (long story).

This means my code is a bit like the snippet below.

if(string.IsNullOrEmpty(myObject.FieldA))
       myObject.FieldA = UpdateFromMethod("FieldA");
if(string.IsNullOrEmpty(myObject.FieldB))
       myObject.FieldB = UpdateFromMethod("FieldB");
if(string.IsNullOrEmpty(myObject.FieldC))
       myObject.FieldC = UpdateFromMethod("FieldC");

Is this something I just need to live with, or is there a better way to do this?

+4
source share
4 answers

- , , . null, , - (??) , , , , .

( ), - :

void Update(ref string value, Func<string> source)
{
    if(string.IsNullOrEmpty(value)) value = source();
}
...
Update(ref myObject.FieldA, UpdateFromMethodA);
Update(ref myObject.FieldB, UpdateFromMethodB);
Update(ref myObject.FieldC, UpdateFromMethodC);

, , .

, , .

+4

.

var type = myObject.GetType();

foreach (var field in type.GetFields())
{
    string value = (string)field.GetValue(myObject);

    if (string.IsNullOrEmpty(value))
    {
        UpdateFromMethod(field.Name);
    }
}
+2

private string _myProp;
public MyProp
{
    get { return _myProp ?? GetValueFromMethod(); }
    set { _myProp = value; }
}

?? coalesce, , null.

, :

public MyProp
{
    get { return IsNullOrEmpty(_myProp) ? GetValueFromMethod() : _myProp; }
    set { _myProp = value; }
}

, ​​ . : , .

 private string _myProp = GetValueFromMethod();
 public MyProp
 {
    get { return _myProp; }
    set { _myProp = IsNullOrEmpty(value) ? GetValueFromMethod() : value; }
 }

, , , , , , , .

+1

. , :

using System;
using System.Linq.Expressions;
using System.Reflection;

public class DataClass
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int Prop4 { get; set; }
    public int? Prop5 { get; set; }
}

public class Test
{
    public static void Main()
    {
        var cls = new DataClass() { Prop1 = null, Prop2 = string.Empty, Prop3 = "Value" };
        UpdateIfNotSet(cls, x => x.Prop1, UpdateMethod);
        UpdateIfNotSet(cls, x => x.Prop2, UpdateMethod);
        UpdateIfNotSet(cls, x => x.Prop3, UpdateMethod);
        UpdateIfNotSet(cls, x => x.Prop4, (x) => -1);
        UpdateIfNotSet(cls, x => x.Prop5, (x) => -1);
        Console.WriteLine(cls.Prop1);  // prints "New Value for Prop1"
        Console.WriteLine(cls.Prop2);  // prints "New Value for Prop2"
        Console.WriteLine(cls.Prop3);  // prints "Value"
        Console.WriteLine(cls.Prop4);  // prints "0"
        Console.WriteLine(cls.Prop5);  // prints "-1"
    }

    public static void UpdateIfNotSet<TOBJ, TPROP>(TOBJ obj, 
                           Expression<Func<TOBJ, TPROP>> prop, 
                           Func<string, TPROP> updateMth)
    {
        var currentValue = prop.Compile().DynamicInvoke(obj);
        var strValue = currentValue as string; // Need to convert to string gracefully so that check against empty is possible
        if (currentValue == null || (strValue != null && strValue.Length == 0))
        {
            var memberAcc = (MemberExpression)prop.Body;
            var propInfo = (PropertyInfo)memberAcc.Member;
            propInfo.SetMethod.Invoke(obj, new object[] { updateMth(propInfo.Name) });
        }
    }

    public static string UpdateMethod(string propName)
    {
        return "New Value for " + propName;
    }
}

UpdateIfNotSet :

  • -,
  • , . , , ,

UpdateIfNotSet , .

The method first compiles the lambda expression and retrieves the current value of the property, invoking the compiled expression. Then it checks to see if it is null or an empty string. In this case, it assigns a new value to the property by calling the provided method.

0
source

Source: https://habr.com/ru/post/1532909/


All Articles