Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c# - ExpandoObject object and GetProperty()

I'm trying to write a generic utility for use via COM from outside .NET (/skip long story). Anyway, I'm trying to add properties to an ExpandoObject and I need to get PropertyInfo structure back to pass to another routine.

using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Reflection;

public class ExpandoTest
{
    public string testThis(string cVariable)
    {
        string cOut = "";

        ExpandoObject oRec = new ExpandoObject { };
        IDictionary<string, object> oDict = (IDictionary<string, object>)oRec;

        oDict.Add(cVariable, "Test");

        Trace.WriteLine(cVariable);
        Trace.WriteLine(oDict[cVariable]);

        PropertyInfo thisProp = oRec.GetType().GetProperty(cVariable);

        if (thisProp != null)
        {
            cOut= "Got a property :)";
        }

        return cOut;
    }
}

Why do I always get a null in in thisProp? I clearly don't understand but I've been staring at it for a day and I'm not getting anywhere. All help/criticism thankfully accepted!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

While using an ExpandoObject it might look like you can add properties at runtime, it won't actually do that at the CLR level. That's why using reflection to get the property you added at runtime won't work.

It helps to think of an ExpandoObject as a dictionary mapping strings to objects. When you treat an ExpandoObject as a dynamic variable any invocation of a property gets routed to that dictionary.

dynamic exp = new ExpandoObject();
exp.A = "123";

The actual invocation is quite complex and involves the DLR, but its effect is the same as writing

((IDictionary<string, object>)exp)["A"] = "123";

This also only works when using dynamic. A strongly typed version of the code above results in a compile-time error.

var exp = new ExpandoObject();
exp.A = "123"; // compile-time error

The actual implementation of ExpandoObject can be found here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...