我有一个名为CottonCandy的对象。 CottonCandy具有一些特性:
很棒的是,如果我可以向CottonCandy添加一些东西,以便可以像这样检索属性:
var colors = cottonCandy["Colors"];
通过阅读this,您似乎可以通过以下方式获得价值:
cottonCandy.GetType().GetProperty("Colors").GetValue(cottonCandy, null);
,您可以轻松地将其包装在方法中:
var colors = cottonCandy.GetPropertyValue("Colors");
但是我真的更喜欢键/值语法cottonCandy["Colors"]
。有什么办法可以做到这一点?
答案 0 :(得分:6)
实际上有一种方法。您可以使用indexers。但是,您需要具有相同的字段类型或在object
类型中输入值。
class CottonCandy
{
private int Mass { get; set; }
private int Volume { get; set; }
private int TotalSugar { get; set; }
private int Colors { get; set; }
public int this[string field]
{
get
{
PropertyInfo propertyInfo = typeof(CottonCandy).GetProperty(field);
if(propertyInfo == null)
throw new ArgumentException("Invalid field");
return (int)propertyInfo.GetValue(this);
}
}
}
答案 1 :(得分:2)
您可以做到
public class CottonCandy
{
public string Mass { get; set; }
public string Volume { get; set; }
public string TotalSugar { get; set; }
public string Colors { get; set; }
public string this[string key]
{
get
{
switch (key)
{
case "Mass":
return this.Mass;
case "Volume":
return this.Volume;
case "TotalSugar":
return this.TotalSugar;
case "Colors":
return this.Colors;
default:
return "";
}
}
set
{
switch (key)
{
case "Mass":
this.Mass = value; break;
case "Volume":
this.Volume = value; break;
case "TotalSugar":
this.TotalSugar = value; break;
case "Colors":
this.Colors = value; break;
default:
break;
}
}
}
}
答案 2 :(得分:1)
这不是键/值语法。但是,如果决定使用扩展名,则可以使用此扩展名方法。此Nuget软件包中有类似的扩展名
public static T GetFieldValue<T>(this object obj, string fieldName)
{
T result;
PropertyInfo propertyInfo = obj.GetType().GetProperty(fieldName);
if (propertyInfo != null)
{
result = (T)propertyInfo.GetValue(obj);
}
else
{
throw new FieldAccessException($"{fieldName} cannot be found");
}
return result;
}
您可以通过this link访问更多扩展程序。也许unit tests提供了有关方法用法和结果的线索。
更新:
您可以像下面这样结合扩展方法和索引器:
public class TestClass
{
public string this[string field]
{
get => this.GetFieldValue<string>(field);
set => this.TrySetFieldValue(field, value);
}
}
答案 3 :(得分:1)
尝试查看对象索引器:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/
一种方法是使用索引器,并使用“ nameof”运算符将索引器字符串值与可用属性进行比较。这会使代码更加冗长,但避免了反思。
但是,请确保这确实是您真正想要的,因为如果您以这种方式访问属性,您将不再获得编译时检查的好处。
答案 4 :(得分:0)
如果您的类是一个简单的数据对象,没有任何行为,并且只有这样的简单属性,则可以将其设置为Dictionary
:
var map = new Dictionary<string, whatever> { { "Colors", ... }, { "Mass", ... } ... };
map["Colors"] = ...;
否则,您应该像已经提到的那样使用反射。