1

I have a class for example:

public class MyClass
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public int SomethingElse { get; set; }
}

Then I want to have a method to be able to call it with arguments as such:

private void KeepingItDRY(MyClass myClass, string valueToSet, ????? PropertyNameToSetItOn)
{
    // some stuff 
    myClass.PropertyNameToSetItOn = valueToSet;
}

But I am not sure how to achieve that?

CSDev
  • 3,177
  • 6
  • 19
  • 37
Bohn
  • 26,091
  • 61
  • 167
  • 254
  • 5
    It is not possible to do it this way, just because it doesn't really sound object-oriented. What you can do is you pass a function to set this value using `Action action`. The question is - why would you need it? How are you going to use it? Particularly, what is "some stuff" - this is the most important thing here. – Yeldar Kurmangaliyev Jun 04 '19 at 14:30
  • 3
    To be clear: you want to be able to call `KeepingItDry(obj, "123", "SomethingElse")` and have it do the same as `obj.SomethingElse = 123;` - is that right? – Marc Gravell Jun 04 '19 at 14:31
  • While this way is not actually possible perhaps what you are looking for can be found here with reflection https://stackoverflow.com/questions/1089123/setting-a-property-by-reflection-with-a-string-value – nalnpir Jun 04 '19 at 14:31
  • 6
    It's perfectly possible (and very simple), but I do agree with the above comment that it's more than likely an XY Problem. Ideas like this are rarely the correct thing to do. If you explain *why* you want to do this you may find a much more simple solution. – Reinstate Monica Cellio Jun 04 '19 at 14:33
  • It's totally possible. It's just not something we would normally want to do. I don't know what the goal is, but in normal scenarios we wouldn't want to set properties (or do anything) using reflection, because the language already gives us ways to set properties and call methods. Unless it's some edge case, if we're not doing it the "normal" way then something may have gone wrong. – Scott Hannen Jun 04 '19 at 14:35
  • 4
    "Don't Repeat Yourself" is a good principle, if you keep it in perspective and remember that it's not ***the only principle***. When you find yourself doing something bizarre like this in order to follow a principle, you're principling wrong. That's kind of a meta-principle. – 15ee8f99-57ff-4f92-890c-b56153 Jun 04 '19 at 14:40
  • What are you trying to do? Whatever it is there are better, faster and safer ways to do it. Perhaps you need dynamic typing, or not. Perhaps you're looking for LINQ expressions, or overcomplicating a simple call. Whatever it is, there's probably a duplicate question for that scenario that explains which option is best – Panagiotis Kanavos Jun 04 '19 at 14:46
  • What does `// some stuff ` hide? That's far more important than the rest of the question. Looks like something that should be placed in the *setter*, not called as a separate method. That `some stuff` could be placed in an extension method, a base class or a validation rule or attribute. It may need to run when calling the setter or when the entire object is "ready" to store. Some of these scenarios are already covered by .NET's validation features – Panagiotis Kanavos Jun 04 '19 at 14:50
  • 2
    Possible duplicate of [Set object property using reflection](https://stackoverflow.com/questions/619767/set-object-property-using-reflection) – Jon Story Jun 04 '19 at 14:51
  • How about using Reflection and use the PropertyNameToSetItOn to gain reference to the myClass property if it exists. Then you can use valueToSet to set the PropertyInfo of myClass. – davedno Jun 04 '19 at 14:57
  • @MarcGravell yes that is correct. – Bohn Jun 04 '19 at 15:02
  • @Bohn, is there any dependency in the "// some stuff" section which would cause the property set not to happen? – Steve Todd Jun 04 '19 at 15:09

1 Answers1

3
class Program
{
    static void Main(string[] args)
    {
        new Program().Run();
    }

    private void Run()
    {
        MyClass myClass = new MyClass();
        KeepingItDRY(myClass, "SomeName", "Name");
        System.Console.WriteLine(myClass.Name);
    }

    private void KeepingItDRY<T>(T target, object value, string property) =>
        typeof(T).GetProperty(property).SetValue(target, value);
}

public class MyClass
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public int SomethingElse { get; set; }
}

Gives:

SomeName
CSDev
  • 3,177
  • 6
  • 19
  • 37