1

I want to do something like: User input name of class + fields. Code finds if a Class with that name has ever been declared. Code creates Class with fields.

I know I can do this with many switch cases, but can I somewhat automate this based on the user input? The name that the user inputs will be the Class name. I'm doing this in C#.

JReno
  • 337
  • 2
  • 15
  • Why would users *ever* need to know the name or make up of a class? And if they have that level of knowledge, why do they need a programmer? – Ňɏssa Pøngjǣrdenlarp Dec 03 '17 at 02:04
  • Just as an example. In reality, I'm getting data from a source, but trying to serialize it into a bunch of different classes. My code would technically be the "user" creating the classes. – JReno Dec 03 '17 at 02:07
  • Creating a class by name is is one of the more frequent questions on SO, you should be able to find the answer. What I don't understand is the "+ fields" part. What do you mean? – Crowcoder Dec 03 '17 at 02:07
  • Fields just being properties within the class. Thanks for the heads up, I think Activator.CreateInstance would be what I'm looking for? – JReno Dec 03 '17 at 02:10
  • If I understand correctly, then yes `Activator.CreateInstance()`. But fields are different than properties, be careful of your terminology. – Crowcoder Dec 03 '17 at 03:05
  • Ahh my bad. I didn't realize they were different. – JReno Dec 03 '17 at 03:42

1 Answers1

1

The System.Reflection.Emit namespace can provide you the tools you need in order to create dynamic classes at runtime. However, if you never used it previously, the task you are trying to accomplish can become quite hard. Of course, premade code could help a lot, and I think that here you can find plenty.

But I propose you an alternative path. Maybe not as flexible, but certainly interesting. It involves the use of DynamicObject class:

public class DynamicClass : DynamicObject
{
    private Dictionary<String, KeyValuePair<Type, Object>> m_Fields;

    public DynamicClass(List<Field> fields)
    {
        m_Fields = new Dictionary<String, KeyValuePair<Type, Object>>();

        fields.ForEach(x => m_Fields.Add
        (
            x.FieldName,
            new KeyValuePair<Type, Object>(x.FieldType, null)
        ));
    }

    public override Boolean TryGetMember(GetMemberBinder binder, out Object result)
    {
        if (m_Fields.ContainsKey(binder.Name))
        {
            result = m_Fields[binder.Name].Value;
            return true;
        }

        result = null;
        return false;
    }

    public override Boolean TrySetMember(SetMemberBinder binder, Object value)
    {
        if (m_Fields.ContainsKey(binder.Name))
        {
            Type type = m_Fields[binder.Name].Key;

            if (value.GetType() == type)
            {
                m_Fields[binder.Name] = new KeyValuePair<Type, Object>(type, value);
                return true;
            }
        }

        return false;
    }
}

Usage example (remember that Field is a small and simple class with two properties, Type FieldType and String FieldName that you have to implement by yourself):

List<Field>() fields = new List<Field>()
{ 
    new Field("ID", typeof(Int32)),
    new Field("Name", typeof(String))
};

dynamic myObj = new DynamicClass(fields);

myObj.ID = 10;
myObj.Name= "A";

Console.WriteLine(myObj.ID.ToString() + ") " + myObj.Name);
Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98
  • Hmm thanks for the insight. I could use Reflection to get the properties of the class. As the main purpose of the program is to make them into pre-defined Xml Serializable classes, I don't think I can use dynamic though. – JReno Dec 03 '17 at 03:48
  • It's a little bit trickier but it's doable. Read the accepted answer here: https://stackoverflow.com/questions/7501846/xml-serialize-dynamic-object – Tommaso Belluzzo Dec 03 '17 at 16:08