1

So I've created a class that inherits DynamicObject

public class MyDynamicObject : DynamicObject{
private Dictionary<string, object> Fields = new Dictionary<string, object>();

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
    return Fields.TryGetValue(binder.Name, out result);
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
    Fields[binder.Name] = value;
    return true;
}
}

And call this class here

public class Program
{
public static void Main()
{
    dynamic person = new MyDynamicObject();
    person.firstname = "Hello";
    Console.WriteLine(person.firstname);
 }
}  

Of course this will work. But I need to create properties from a string array like

string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic person = new MyDynamicObject();
foreach(var f in fields)
{
  person.f = "hello";
}

So the output will be person.taxi, person.newcol, person.addrs, person.gender

Is this possible?

4
  • Take a look at the built-in ExpandoObject; Essentially you'll have to expose a method for adding fields to the dictionary. Commented Sep 8, 2017 at 11:50
  • I think your question might be answered at stackoverflow.com/a/4938442/1462295 Commented Sep 8, 2017 at 11:57
  • Regarding what the first commenter said, why not just have a dictionary do this? person[f] ="hello" Commented Sep 8, 2017 at 12:08
  • I already did it using ExpandoObject and its working, but my requirement is to create a class that will have a dynamic properties and can be instantiated, I dont know if its possible Commented Sep 8, 2017 at 12:21

2 Answers 2

1

Expose the Fields dictionary in some way, or (better) a method that allows one to explicitly set a property by name.

Note that ExpandoObject already does this, as it can be cast to IDictionary<string, object> and then you

ExpandoObject eo = new ExpandoObject();
IDictionary<string, object> dict = eo;
dynamic d = eo;
dict["MyProperty"] = 42;
Console.WriteLine(d.MyProperty); // 42

If you can't just use ExpandoObject itself, you can copy its approach.

Sign up to request clarification or add additional context in comments.

Comments

1

Okay so based on the suggestion of @Jon Hanna, I came up with a solution that fits my requirements. I created a new Add method which accept a name. Below is the updated code I used.

public class DynamicFormData : DynamicObject
{
    private Dictionary<string, object> Fields = new Dictionary<string, object>();

    public int Count { get { return Fields.Keys.Count; } }

    public void Add(string name, string val = null)
    {
        if (!Fields.ContainsKey(name))
        {
            Fields.Add(name, val);
        }
        else
        {
            Fields[name] = val;
        }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (Fields.ContainsKey(binder.Name))
        {
            result = Fields[binder.Name];
            return true;
        }
        return base.TryGetMember(binder, out result); 
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (!Fields.ContainsKey(binder.Name))
        {
            Fields.Add(binder.Name, value);
        }
        else
        {
            Fields[binder.Name] = value;
        }
        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (Fields.ContainsKey(binder.Name) &&
            Fields[binder.Name] is Delegate)
        {
            Delegate del = Fields[binder.Name] as Delegate;
            result = del.DynamicInvoke(args);
            return true;
        }
        return base.TryInvokeMember(binder, args, out result);
    }
}

Then I just call it like this.

string[] fields = new string[]{"taxid","newcol","addrs","gender"};
dynamic formData = new DynamicFormData();

foreach(string field in fields)
{
    formData.Add(field, null);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.