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

本文关键字:属性 访问 方法 字符串 表示 | 更新日期: 2023-09-27 18:31:27

我有一个包含一堆集合的类

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")都是空的。

任何帮助,不胜感激。

解决方式如下

关于反射将队列公开为属性并使用 这是一个很好的解决方案,

   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 

在回避循环中利用 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);
            }
        }
    }
}

仍然觉得我应该在某个地方使用枚举,但难题 暂时解决了。 非常感谢大家。

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

你没有属性,你有字段。所以你需要GetField方法。此外,这些字段是私有的,您需要指定BindingFlags.NonPublic标志:

myInfoChain.GetType()
.GetField(qName, BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(myInfoChain,i);

但是无论我做什么,GetProperty("_firstQ")都是空的。

那是因为您没有属性_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 };
    }
}

您可以myInfoChain.MyQueues[n]访问第 n 个队列......无需反思。

目前,您的队列是字段,而不是属性。 尝试将它们定义为

FirstQ { get; set; }

并在构造函数中分配队列。 然后GetProperty("FirstQ")应该能得到你需要的东西。