我有一个有很多集合的课程
Class MyInfoClass
{
Queue<float> firstQ = new Queue<float>();
Queue<float> secondQ = new Queue<float>();
Queue<float> thirdQ = new Queue<float>();
Queue<float> fourthQ = new Queue<float>();
Queue<float> fifthQ = new Queue<float>();
}
另一个具有这些集合名称的字符串表示
class myParamClass
{
internal static string[] Chain =
{
"firstQ",
"secondQ",
"thirdQ",
"fourthQ",
"fifthQ"
}
}
我想使用字符串表示法访问集合
class Program
{
static void Main(string[] args)
{
MyInfoClass myInfoChain = new MyInfoClass();
float i = 0;
//attempt to set
foreach (string qName in MyParamClass.Chain)
{
i++;
myInfoChain.GetType().GetProperty(qName).SetValue(myInfoChain,i);
}
//attempt to get
foreach (string qName in MyParamClass.Chain)
{
Trace.WriteLine(myInfoChain.GetType().GetProperty(qName).GetValue(myInfoChain,null));
}
}
}
我正在尝试使用反射但继续获取空对象异常,但并不真正关心我是如何实现这一点的。我尝试使用枚举但是帽子过于复杂化了,我尝试将字段作为属性公开并调用get set方法。我像仓鼠一样四处转转。
具体来说,我需要知道如何访问上面的集合,但一般来说,如何使用(属性/字段/方法)名称的字符串访问类的成员(属性/字段/方法)将是非常有用吗?
我所读到的内容一直指向类似的东西
var letMeIn = typeof (MyInfoClass).GetProperty("_firstQ").GetValue(myInfoChain,null);
????
但无论我做什么,GetProperty(“_ firstQ”)都是null。
解决如下
关于将队列暴露为属性和使用的反射 这是一个很好的解决方案,
var letMeIn = typeof (MyInfoClass).GetProperty("FirstQ")
.GetValue(myInfoChain,null);
... but I never managed to get the matching .SetValue() method working. What worked really well was the array of Queues
class MyInfoClass
{
private Queue<float> _firstQ = new Queue<float>();
private Queue<float> _secondQ = new Queue<float>();
private Queue<float> _thirdQ = new Queue<float>();
private Queue<float> _fourthQ = new Queue<float>();
private Queue<float> _fifthQ = new Queue<float>();
public Queue<float>[] MyQueues
{
get
{
return new[] { _firstQ, _secondQ, _thirdQ, _fourthQ, _fifthQ };
}
}
}
Which allowed me to iterate the collections byte index, and also to
在recusive循环(我的核心目标)中利用LINQ,如下所示
class Program
{
static List<double> SeperateWorkMethod(List<double> d, float val)
{
//stuff/work on d, List<double>
return d;
}
static void Main(string[] args)
{
MyInfoClass myInfoChain = new MyInfoClass();
float x = 0;
List<double> temp = new List<double>();
foreach (Queue<float> t in myInfoChain.MyQueues)
{
x = x + 123;
t.Enqueue(x);
temp.Add(t.Average());
temp.AddRange(t.Select(subType => subType.customField));
}
for (int index = 0; index < myInfoChain.MyQueues.Length; index++)
{
myInfoChain.MyQueues[index].Aggregate(temp, SeperateWorkMethod);
}
}
}
}
我仍然觉得我应该在某处使用枚举,但这个难题 现在解决了。非常感谢所有人。
答案 0 :(得分:3)
你没有属性,你有字段。所以你需要GetField
方法。而且字段是私有的,你需要指定BindingFlags.NonPublic
标志:
myInfoChain.GetType()
.GetField(qName, BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(myInfoChain,i);
答案 1 :(得分:2)
但无论我做什么,GetProperty(“_ firstQ”)都是null。
那是因为你没有财产_firstQ
。添加一个......(除了你的字段)
public Queue<float> _firstQ { get { return firstQ; } }
并且上面的代码示例应该有效。
请注意,在C#属性中通常以大写字母开头,所以
public Queue<float> FirstQ { get { return firstQ; } }
会更加惯用。
事实上,如果您只需动态访问第n个队列,则根本不需要反射:
public Queue<float>[] MyQueues
{
get
{
return new[] { firstQ, secondQ, thirdQ, fourthQ, fifthQ };
}
}
你只需要访问第n个队列myInfoChain.MyQueues[n]
......不需要反思。
答案 2 :(得分:1)
目前你的队列是字段,而不是属性。尝试将它们定义为
FirstQ { get; set; }
并在构造函数中分配队列。然后GetProperty(“FirstQ”)应该可以满足您的需求。