2

Say I have a function How do i set the property on the record

public void SetProperty<TRecord, TEnum>(TRecord item,  
                                        Func<TRecord, TEnum> property, string enumValue )
   where TEnum : struct
   where TRecord : class
{
     TEnum enumType;
     if (Enum.TryParse(enumValue, true, out enumType))
     {
         //How Do I set this?
         property.Invoke(item) = enumType;
     }
}

I'd prefer not to switch this to an expression. Does anybody know how to set the property?

johnny 5
  • 19,893
  • 50
  • 121
  • 195
  • 3
    That's totally impossible. Given a delegate that (you assume) calls a property getter, there is no way to get the setter. – SLaks Feb 08 '16 at 19:59
  • 1
    What problem are you trying to solve? Instead of showing us your proposed solution to some unknown problem, tell us what the problem is, and we'll figure out how to solve it. – Robert Harvey Feb 08 '16 at 19:59
  • @SLaks what would I have to change to get the setter? Pass an action, use reflection, or expression tree? – johnny 5 Feb 08 '16 at 20:01
  • You're missing the point. "How do I set the property on the record" is not your problem; it's an *implementation detail.* – Robert Harvey Feb 08 '16 at 20:02
  • @RobertHarvey I'm trying to create a function that will generically convert any string property to its enumeration value and assign it – johnny 5 Feb 08 '16 at 20:02
  • 1
    the Easy way would be to just change from `Func` to `Action` then just call it with `SetProperty(item, (r,e)=>r.Propery = e, "value")` – Matthew Whited Feb 08 '16 at 20:03
  • @Hogan Record can be any class that contains an Enum Type – johnny 5 Feb 08 '16 at 20:04
  • @johnny5: Yes; any of those options will work fine. – SLaks Feb 08 '16 at 20:04
  • 1
    [How do I convert a string to an enum in C#?](http://stackoverflow.com/questions/16100/how-do-i-convert-a-string-to-an-enum-in-c) – Robert Harvey Feb 08 '16 at 20:04
  • [Enum.Parse()](https://msdn.microsoft.com/en-us/library/essfb559(v=vs.110).aspx) – Robert Harvey Feb 08 '16 at 20:05
  • @RobertHarvey I want the assignment to occur not the conversion – johnny 5 Feb 08 '16 at 20:06
  • Then take the result, and assign it. I don't understand what you're saying. Can you provide an example of your expected input and output? – Robert Harvey Feb 08 '16 at 20:06
  • @RobertHarvey there is more logic occuring with it to add errors to the trecord class i didnt feel it was important to add with the issue sorry i should have clarified – johnny 5 Feb 08 '16 at 20:07
  • @MatthewWhited where is the SetProperty Function? – johnny 5 Feb 08 '16 at 20:07
  • I posted my answer below... but don't do this. Do it as Robert is Suggesting. – Matthew Whited Feb 08 '16 at 20:08
  • 2
    SetProperty is most likely not going to help you here, unless you think you need the additional level of indirection that Reflection provides, but I don't think you do. – Robert Harvey Feb 08 '16 at 20:08
  • There is more logic with the function I was just simplifying the solution but I think @MatthewWhited solution will work just need to test it – johnny 5 Feb 08 '16 at 20:11

1 Answers1

7
public void SetProperty<TRecord, TEnum>(TRecord item,
                                Action<TRecord, TEnum> property, string enumValue)
    where TEnum : struct
    where TRecord : class
{
    TEnum enumType;
    if (Enum.TryParse(enumValue, true, out enumType))
    {
        property(item, enumType);
    }
}

better way...

public TEnum? AsEnum<TEnum>(string enumValue)
    where TEnum : struct
{
    TEnum enumType;
    if (Enum.TryParse(enumValue, true, out enumType))
    {
        return enumType;
    }
    return default(TEnum);
}

usage examples...

myObj.Prop = AsEnum<MyEnum>("value") ?? MyEnum.Default;
//versus 
SetPropery<MyObject, MyEnum>(myobj, (r, e) => r.Prop = e, "value");
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
  • 1
    Without using `Expression` (which the OP said he wanted to avoid), this is the only way to do it. However, it makes the calling code a lot more complicated, both because it introduces a second lambda argument and because the generic `TEnum` type can no longer be inferred implicitly. – StriplingWarrior Feb 08 '16 at 20:12
  • 1
    I don't disagree... the pattern based on his request is not pretty. – Matthew Whited Feb 08 '16 at 20:14