C#有没有办法从类中获取字段的引用并使用引用来调用方法?

时间:2017-11-10 01:26:23

标签: c#

C#Question .Net version 4.6.1

我有一个如下所示的类,在一个函数中我创建了一个类的实例。我想从类实例创建对field(s)的引用,并在类变量“Name”和“Description”上调用方法“Insert”。

我使用谷歌搜索:“通过获取对类字段的引用 在C#中的反射。我确实找到了有关反射的stackoverflow的信息,但它没有讨论调用方法。我能够使用它来查找看起来像指针的东西。但是我无法一直调用方法在参考文献中。我要么向谷歌提出错误的问题,要么我想做的事情是不可能的 C# Reflection - Get field values from a simple class

    Class AClass1
    {
        public String Action = String.Empty;
        public List<KeyValuePair<String, String>> Description = new  List<KeyValuePair<string, string>>();
        public List<KeyValuePair<String, String>> Name= new List<KeyValuePair<string, string>>();
    }


    // Psudo code:
    // The code has been reduced down to show the problem.  Error handling
    // etc has been removed. This may not compile because I had to 
    // reduce down the code to show what I am trying to accomplish. Any
    // suggestions for creating a reference to a class variable and calling
    // its methods would be appreciated.  If needed I can create a small 
    // sample that does compile but I think the sample provided shows 
    // what I am trying to accomplish.  If not let me know and I will
    // scale down further.


public void ProcessFeature1(String fieldName, String value1, String value2)
{
    AClass1 featureToManage = new AClass1();

    KeyValuePair<string, string> entry = new KeyValuePair<string, string>(value1, value2);
    if (entry != null)
    {
        // something along these lines is preferred if possible
        var ptrField = featureToManage.GetType().GetField(fieldName).FieldHandle;
        if (ptrField != null)
        {
            // the problem is figuring how to turn the value from reflection into
            // something I can call directly.  I have tried casting to the same
            // type as the variable in the class (not shown here) 
            // but it did not work or I did it wrong.  When I say it does not
            // work the run-time information does not show the method and the
            // compiler complains generally saying no such method Insert found.
            ptrField.Insert(0, entry);
        }
        else
        {
            // this works but would prefer to lookup the
            // the field in the class and call methods so I
            // 1. have less code
            // 2. do not have to hard code the name of the field.
            switch (fieldName)
            {
                case "Name":
                    {
                        featureToManage.Name.Insert(0, entry);
                        break;
                    }
                case "Description":
                    {
                        featureToManage.Description.Insert(0, entry);
                        break;
                    }
                default:
                    {
                        // something bad happened
                        break;
                    }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

听起来你正在寻找GetValue()方法。

使用FieldInfo从Type中获取GetField()后,只需调用其GetValue()方法,传递要从中获取字段值的对象实例(在本例中为featureToManage),然后将结果值转换为适当的类型(在本例中为List<KeyValuePair<string, string>>)。

以下是代码中的内容:

public void ProcessFeature1(string fieldName, string value1, string value2)
{
    AClass1 featureToManage = new AClass1();

    // Get the FieldInfo for the requested fieldName
    FieldInfo fieldInfo = featureToManage.GetType().GetField(fieldName);

    // Use the fieldInfo to get the value of the field from the target instance
    var targetList = (List<KeyValuePair<string, string>>)fieldInfo.GetValue(featureToManage);

    // now we can use the value as normal
    var entry = new KeyValuePair<string, string>(value1, value2);
    targetList.Insert(0, entry);
}

请注意,在C#6中,您可以使用nameof()运算符来避免在使用反射时对类,字段和属性名称进行硬编码,例如:

ProcessFeature1(nameof(AClass1.Description), "foo", "bar");