Home > Enterprise >  Using Func Delegate to set DateTime fields of the class
Using Func Delegate to set DateTime fields of the class

Time:01-26

I have a class with two DateTime fields, I want to have one shared method to set both of them. Would it be possible somehow to do so with Func Delegate?

    private void SetDateTimeField(MyClass class, Func<SupportTicket, DateTime> selector, DateTime date)
    {
      //using selector to select a field of the class and set date parameter to it
    }

and then use it like:

SetDateTimeField(class, c => c.DateTimeField1, DateTime.UtcNow);
SetDateTimeField(class, c => c.DateTimeField2, DateTime.UtcNow);

This question less about practicality of it, but rather understanding how to do it. Is it possible?

CodePudding user response:

If DateTime fields are actually fields (not properties), you can use ref.

var c = new MyClass();

MyClass.SetDateTimeField(c, c => ref c.dt1, DateTime.Now);
MyClass.SetDateTimeField(c, c => ref c.dt2, DateTime.Now);

public class MyClass {
    public DateTime dt1;
    public DateTime dt2;
    
    public delegate ref DateTime Selector(MyClass c);
    
    public static void SetDateTimeField(MyClass c, Selector sel, DateTime dt) {
        sel(c) = dt;
    }
}

CodePudding user response:

Instead of passing a function, pass a function expression. You can then derive the property from the expression and set its value.

public class SupportTicket
{
    public DateTime DT1 { get; set; }
    public DateTime DT2 { get; set; }
}


private static void SetDateTimeField<TObj, TProp>(TObj obj, Expression<Func<TObj, TProp>> selectorExpr, TProp date)
{
    // Get the body of the function as a member access expression
    MemberExpression memberExpr = selectorExpr.Body as MemberExpression;
    if (memberExpr != null)
    {
        // Get the property from the member access expression and set the value
        MemberInfo memberInfo = memberExpr.Member;
        PropertyInfo propertyInfo = memberInfo.DeclaringType.GetProperty(memberInfo.Name);
        propertyInfo.SetValue(obj, date);
    }
    else
    {
        throw new Exception("You must use a member access expression");
    }
}

Sample usage:

SupportTicket ticket = new SupportTicket();
DateTime dt = DateTime.Now;
SetDateTimeField(ticket, e => e.DT1, dt);
SetDateTimeField(ticket, e => e.DT2, dt);

Console.WriteLine(ticket.DT1);
Console.WriteLine(ticket.DT2);
Console.ReadLine();

CodePudding user response:

If you want to change a property based on name you can do it like this:

private void SetDateTimeField(MyClass classX, String selector, DateTime dateX)
{
  //using selector to select a field of the class and set date parameter to it
  var prop = typeof(MyClass).GetProperty(selector);

  prop.SetValue(classX, dateX);


}

SetDateTimeField(class, "DateTimeField1", DateTime.UtcNow);
SetDateTimeField(class, "DateTimeField2", DateTime.UtcNow);
  •  Tags:  
  • c#
  • Related