[C #] Use the indexer to treat class members (properties) like a list
I want to be able to access the property members of the data type class with an indexer like a list.
Subject
Make the properties of the UserInfo class below accessible by the indexer.
UserInfo.cs
public class UserInfo
{
public UserInfo(List<String> userList)
{
ID=userList[0];
Name=userList[1];
Password=userList[2];
email=userList[3];
}
public string ID{get;set;}
public string Name{get;set;}
public string Password{get;set;}
public string email{get;set;}
}
Pre-preparation Access with subscript
userInfo.cs
public class UserInfo
{
public UserInfo(List<String> userList)
{
var properties = typeof(UserInfo).GetProperties();
{
for (var i = 0; i < userList.Count; i++)
{
var name = properties[i].Name;
//Initialize properties collectively with userList
this[name] = userList[i];
}
}
}
public string ID{get;set;}
public string Name{get;set;}
public string Password{get;set;}
public string email{get;set;}
private string this[string propertyName]
{
get => typeof(UserInfo).GetProperty(propertyName).GetValue(this).ToString();
set => typeof(UserInfo).GetProperty(propertyName).SetValue(this, value);
}
}
Commentary
string this[string propertyName]
By adding this property, you can access by subscript.
get
–typeof (class name) .GetProperty (propertyName) .GetValue (this)
↑ Since the return value of GetValue is object type, it is converted to string type.
set
–typeof (class name) .GetProperty (propertyName) .SetValue (this, value)
constructor
typeof(UserInfo).GetProperties()
Get class properties as an array.properties[i].Name
Since each property name can be acquired, loop processing becomes possible.
It doesn’t make much sense as it is, so make it accessible with an indexer.
Access with production 1 indexer
Add the following to the UserInfo class
userInfo.cs
private List<string> NameList;
public string this[int num]
{
get => this[NameList[num]];
set => this[NameList[num]] = value;
}
NameList is used as a list containing a list of property names (used for indexing property names).
string this[int num]
Wrap this [string propertyName]
.
Convert to the subscript of this [string propertyName] with NameList [num]
.
This will allow you to access it with an indexer.
However, this alone cannot be used as an enumeration type.
Production 2 Allows enumeration
Inherit IEnumerable and create IEnumerable
By implementing GetEnumerator, it can be handled as an enumeration type.
userInfo.cs
//Change of UsefInfo, describe only additional parts
public class UserInfo : IEnumerable<string>
{
//GetEnumerator implementation
public IEnumerator<string> GetEnumerator()
{
for (var i = 0; i < NameList.Count; i++)
{
yield return this[i];
}
}
//IEnumerable(Non-generic type)Also implements GetEnumerator
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Overall picture
UserInfo.cs
public class UserInfo : IEnumerable<string>
{
public UserInfo(List<String> userList)
{
var properties = typeof(UserInfo).GetProperties();
NameList = new List<string>();
//Extract each Name from properties
foreach (var (name, index) in properties.Select((prop, index) => (prop.Name, index)))
{
if(index == properties.length - 1)
{
//The end of the array is this property, so skip it
break;
}
//Create a list of UserInfo property names
NameList.Add(name);
//Initialize all properties
this[name] = headerlist[index];
}
}
public string ID{get;set;}
public string Name{get;set;}
public string Password{get;set;}
public string email{get;set;}
//Property index usage
private List<string> NameList;
//For access by subscript
private string this[string propertyName]
{
get => typeof(UserInfo).GetProperty(propertyName).GetValue(this).ToString();
set => typeof(UserInfo).GetProperty(propertyName).SetValue(this, value);
}
//For access with indexer
public string this[int num]
{
get => this[NameList[num]];
set => this[NameList[num]] = value;
}
//For assignment to list type
public List<string> ToList()
{
var res = new List<string>();
NameList.ForEach(name => res.Add(this[name]));
return res;
}
public IEnumerator<string> GetEnumerator()
{
for (var i = 0; i < NameList.Count; i++)
{
yield return this[i];
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
result
var User=new UserInfo(new List<string>{"012","user","pass","[email protected]"});
//Access by subscript
User[0] = "dummy";
if(User.ID == "dummy")
{
//match
}
Console.WriteLine(User[3]);
//[email protected]
foreach(var val in User)
{
Console.WriteLine(val);
//012
//user
//pass
//[email protected]
}
var list=User.ToList()
//list:{"012","user","pass","[email protected]"}
You can now access with an indexer and loop with foreach.
I was able to do it, but I feel that there are many steps and it is redundant.
I would appreciate it if you could tell me if there is a better way.