0

Help me, is it possible in C# to make a dynamically created class whose number of properties and their types are not known in advance?

For example, there is a POCO class and it is necessary to load a file template (for example - XML) when loading, in which the names of objects (properties), their types and values will be specified.

It seems to me that this can be done through a dictionary and a wrapper class (maybe I'm wrong and this is a bad decision). But I can't figure out how to dynamically unpack from object to the correct realy class without creating dozens of as conditions?

public static class Program
{
    public static void Main()
    {
        Dictionary<string, ElemType> keys = new Dictionary<string, ElemType>();
        keys.Add(
            "UserID", new ElemType() { NameType = "System.Int32", ValueType = "123" }
            );
        keys.Add(
            "UserName", new ElemType() { NameType = "System.String", ValueType = "abc" }
            );

        var type = Type.GetType(keys["UserID"].NameType);
        ///var elem = (???type)Activator.CreateInstance(type);
    }
}

public class ElemType
{
    public string NameType { get; set; }
    public object ValueType { get; set; }
}
KUL
  • 391
  • 2
  • 15
  • Have a look at [Dynamic objects](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects) – McNets May 06 '22 at 14:36
  • This also may help: https://stackoverflow.com/questions/3862226/how-to-dynamically-create-a-class – Ramin Rahimzada May 06 '22 at 14:37
  • 2
    why not just use Linq2Xml in order to read the xml? What exactly do you want to achieve here? Could you give an example of your data and the desired output? – MakePeaceGreatAgain May 06 '22 at 14:39
  • Did you take a look at this? [dynamically-add-c-sharp-properties-at-runtime](https://stackoverflow.com/questions/15819720/dynamically-add-c-sharp-properties-at-runtime) – DenisMicheal.k May 06 '22 at 14:39
  • @McNets I have no experience with `Dynamic objects` with this technology yet, if this is the only option, then I will have to study it. Thanks! – KUL May 06 '22 at 14:54
  • @MakePeaceGreatAgain I want to analyze a log file of unknown structure. The structure will be described in advance by the template user. After analyzing the template, build a database and write typed data. – KUL May 06 '22 at 14:54
  • @KUL If your goal is to analyze a file then you're *far* better off not doing this. Trying to dynamically generate a new type with a structure not known at compile time is way harder than parsing a file into a single some data structure or class that can have dynamic data. You don't need to have a new class with new properties for each value, just use a dictionary, list, etc. to store the values. That's *much* easier to work with. – Servy May 06 '22 at 18:58
  • I also wonder if you might eventually be best served by [JSON.Net](https://www.newtonsoft.com/json)? – Wyck May 06 '22 at 19:05

1 Answers1

1

You can use an ExpandObject which can define properties during the runtime. Below is a very simple working prototype

    static void Main(string[] args)
    {
        // Define a type with the following properties
        //  string  Name
        //  int     Age
        //  bool    Alive


        dynamic test2 = CreateInstance(
            ("Name", "John"),
            ("Age", 50),
            ("Alive", true));

        Console.WriteLine($"Name:{test2.Name} Age:{test2.Age}");
    }

    static dynamic CreateInstance(params (string name, object value)[] properties)
    {
        dynamic eo = new ExpandoObject();
        var dict = (IDictionary<string, object>)eo;

        foreach (var item in properties)
        {
            dict[item.name] = item.value;
        }

        return eo;
    }
JAlex
  • 1,486
  • 8
  • 19
  • It seems this is what I need! Thanks! `dynamic elem = new ExpandoObject(); elem.UserName = "KUL"; elem.UserID = 0; var tName = elem.UserName.GetType(); var tID = elem.UserID.GetType();` – KUL May 08 '22 at 12:08