使用属性名称的字符串表示形式访问类属性和方法

时间:2014-11-22 14:07:09

标签: c#

我有一个有很多集合的课程

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);
            }
        }
    }
}
  

我仍然觉得我应该在某处使用枚举,但这个难题   现在解决了。非常感谢所有人。

3 个答案:

答案 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”)应该可以满足您的需求。