I'm trying to learn how to pass some type of an argument that will tell a method which property it should edit.
I'm trying to save an object with two string lists to a json file. So I have an "Add" method that adds a string to one of the lists, and that's where I need a parameter that determines/points/refers to which list I want the method to add to.
I've tried to use Enums but then I'll have to use a lot of if statements in the method and I feel like there should be a better way to do it.
I've tried the ref keyword but then I have to create the object (before calling the "Add" method) and pass it to the method, but I don't want that, I want the method to create an object on it's own and know which list it must edit.
NOTE: the following code has generic names and doesn't use lists and the whole json stuff for the sake of simplicity and clarity
NOTE: the next code is taken from a console app
NOTE: the "ChangeStuff" method's parameter (refProp) isn't right because I don't know what else to put there.
So I want the method to work something like this:
class Stuff
{
public string One = "Normal";
public string Two = "Normal";
}
class Program
{
static void Main(string[] args)
{
var StuffObject = new Stuff();
ChangeStuff(StuffObject.One);
}
static void ChangeStuff(refProp)
{
Stuff StuffObject = new Stuff();
StuffObject.refProp = "Changed";
Console.WriteLine(StuffObject.refProp);
}
}
I expect ChangeStuff to make an object and change the property that "refProp" points to and then writes that property's value to the console.
You could make use of Expressions for referring properties in your class in order to change them. For example,
static void Main(string[] args)
{
var stuffObject = new Stuff();
var result = ChangeStuff(stuffObject,x=>x.Two);
}
static T ChangeStuff<T>(T target,Expression<Func<T,object>> exp)
{
var memberSelectorExpression = exp.Body as MemberExpression;
if (memberSelectorExpression != null)
{
var property = memberSelectorExpression.Member as PropertyInfo;
if (property != null)
{
property.SetValue(target, "Changed", null);
}
}
return target;
}
Please note, you need to make your One and Two in the Class Stuff as Properties.
class Stuff
{
public string One {get;set;} ="Normal";
public string Two {get;set;} ="Normal";
}
You could extend it further by passing the "New Value" as parameter.
static TSource ChangeStuff<TSource,TValue>(TSource target,Expression<Func<TSource,TValue>> exp,TValue newValue)
{
var memberSelectorExpression = exp.Body as MemberExpression;
if (memberSelectorExpression != null)
{
var property = memberSelectorExpression.Member as PropertyInfo;
if (property != null)
{
property.SetValue(target, newValue, null);
}
}
return target;
}
Now you could call the method as
ChangeStuff(stuffObject,x=>x.Two,"This is new value");