I have a class like this in a legacy system
public class MyObj
{
public string Pro1 { get; set; }
public string Pro2 { get; set; }
public string Pro3 { get; set; }
public string Pro4 { get; set; }
public string Pro5 { get; set; }
public string Pro6 { get; set; }
public string Pro7 { get; set; }
public string Pro8 { get; set; }
}
Unfortunately the Properties Pro1...Pro8 has been used everywhere in the application. To facilitate access, the developer opted to use reflection to loop through using property names.
typeof(MyObj).GetProperty($"Pro{index}");
This is really troublesome.
I would like to create a ordered list somehow to get rid of the reflection. Something like this
public List<string> PropertiesAsList()
{
Pro1,Pro2,Pro3,Pro4...
}
Which later I can do
PropertiesAsList[0] = "This should set to Pro1";
I can not alter or remove the propeties Pro1..Pro4 to list as they are required by other parts in the system. I am only trying a way to access them easily without reflection
I already know that I can create a function
SetPropertyByIndex(int index, string value)
{
//huge switch-case?
}
Is there a good/better way I can achieve what I want?
CodePudding user response:
Good thing these are properties! You can change the implementations of the getters and setters so that they are backed by a list instead.
public class MyObj
{
private List<string> pros = new List<string> {
...
};
public string GetPro(int index) => pros[index 1];
public void SetPro(int index, string newValue) => pros[index 1] = newValue;
public string Pro1 {
get => pros[0];
set => pros[0] = value;
}
public string Pro2 {
get => pros[1];
set => pros[1] = value;
}
// and so on...
}
CodePudding user response:
I'll use a simplified example. Change this:
public class MyObj
{
public string Pro1 { get; set; }
public string Pro2 { get; set; }
}
to this:
public class MyObj
{
public string[] Properties { get; } = new string[] { null, null };
public string Pro1
{
get { return Properties[0]; }
set { Properties[0] = value;; }
}
public string Pro2
{
get { return Properties[1]; }
set { Properties[1] = value; }
}
}
I've used an array so that the length cannot be changed. The existing properties will continue to look and act the same way as before from the outside but you now also have the Properties
property that you can get and then index to get or set a value in the same array that is now backing the old properties.
CodePudding user response:
Just implement the getter:
class Foo
{
public string P1 {get; set;}
public string P2 {get; set;}
public IEnumerable<string> Ps
{
get
{
yield return P1;
yield return P2;
}
}
}
Now you can
var foo = new Foo {
P1 = "one",
P2 = "two"
};
foreach (var p in foo.Ps)
{
Console.Write(p);
}
CodePudding user response:
You were so close:
public class MyObj
{
public string Pro1 { get; set; }
public string Pro2 { get; set; }
public string Pro3 { get; set; }
public string Pro4 { get; set; }
public string Pro5 { get; set; }
public string Pro6 { get; set; }
public string Pro7 { get; set; }
public string Pro8 { get; set; }
public List<string> PropertiesAsList() => new List<string>()
{
Pro1, Pro2, Pro3, Pro4, Pro5, Pro6, Pro7, Pro8,
};
public string this[int index] => PropertiesAsList()[index - 1];
}
Now you can write this:
var myObj = new MyObj() { Pro4 = "Hello" };
Console.WriteLine(myObj[4]);
It would write out "Hello".