5

I have this structure.

public class FirstClass
{
   public List<Foo> FooList{ get; set; }
}

public class Foo{
   //Ex:
   //public string Name{ get; set; }  
}

public List<Foo> GetFoo(){
//I'm use Firstclass like this here typeof(FirstClass);
//I want create here dynamic property for Foo class.
}

And my problem is, i want create property for "Foo" class from "GetFoo()" function. Same time, this function return "List" "Foo" type. I'm research "Dynamically Add C# Properties at Runtime", "How to dynamically create a class in C#?" but the answers in these links are not referenced as return values or referenced to another class. How i can do this?

Muhammet Can TONBUL
  • 3,217
  • 3
  • 25
  • 37

2 Answers2

2

You can dynamically create classes, which inherits Foo, with any additional properties. Thus you can add instances of those dynamic classes into List<Foo>.

To do so, one can generate a code string like following:

var bar1Code = @"
public class Bar1 : Foo
{
    public Bar1(int value)
    {
        NewProperty = value;
    }
    public int NewProperty {get; set; }
}
";

Then compile it using CSharpCodeProvider:

var compilerResults = new CSharpCodeProvider()
    .CompileAssemblyFromSource(
        new CompilerParameters
        {
            GenerateInMemory = true,
            ReferencedAssemblies =
            {
                "System.dll",
                Assembly.GetExecutingAssembly().Location
            }
        },
        bar1Code);

Then one can create an instance of Bar1, add it to List<Foo> and, e.g. cast it to dynamic to access the dynamic property:

var bar1Type = compilerResults.CompiledAssembly.GetType("Bar1");
var bar2Type = compilerResults.CompiledAssembly.GetType("Bar2"); // By analogy

var firstClass = new FirstClass
{
    FooList = new List<Foo>
    {
        (Foo)Activator.CreateInstance(bar1Type, 56),
        (Foo)Activator.CreateInstance(bar2Type, ...)
    }
};

var dynamicFoo = (dynamic)firstClass.FooList[0];
int i = dynamicFoo.NewProperty; // should be 56
stop-cran
  • 4,229
  • 2
  • 30
  • 47
  • How can I use such a class at runtime? For ex if I have a library that needs access to this class won't it give compilation error? – kuldeep May 18 '20 at 16:54
  • @kuldeep it is possible to use this class from a library. For example Castle.DynamicProxy and widely used Moq package use similar pattern to automatically implement interfaces in runtime. – stop-cran May 19 '20 at 03:46
  • is there a tutorial or sample on this? I am struggling to find anything on Google. I could create a class on the fly that has my models but I am not sure now how to use these model classes – kuldeep May 19 '20 at 04:13
  • @kuldeep it depends on your purposes. In general it's a good idea to inherit "on-the-fly" classes from some interfaces, known in the compile time. Then one would be able to cast them to that interfaces in the code and thus use their functionality. For example, aforementioned Moq package has class `Mock` which is capable to implement virtual methods of `T` on the fly. It also has an `Object` property with type `T` which represents the implementation with overridden members of `T`. – stop-cran May 19 '20 at 04:38
  • use case is that I want to use a custom serialization libary, because it includes lot of boilerpate code that takes care of things such as Bigendian, numberformatting etc. Now so far this process of generating the classes is at compile time, and we want to have ability to do it dynamically via json file. Two choices are there, either use dynamic parsing via dynamic object OR use code generation (based on json structure) to dump model classes and use existing serializer library for that, clearly in the prior case we can not use this custom serializer library, hence the question. – kuldeep May 19 '20 at 07:28
  • @kuldeep in this case it's possible to generate C# code with classes from JSON on a custom build step, e.g. as it's done with gRPC - C# classes are genrated from protobuf. In .Net 5 a new powerful way is introduced - [Source Generators](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/). – stop-cran May 19 '20 at 09:27
0

Why don't you just use a Dictionary;

public class Foo
{
    public Dictionary<string, object> Properties;

    public Foo()
    {
        Properties = new Dictionary<string, object>();
    }
}
public List<Foo> GetFoo()
{
    var item = new Foo();
    item.Properties.Add("Name","Sample");
    item.Properties.Add("OtherName", "Sample");
    return new List<Foo>{ item };
}

Adding property for a class in runtime, it is not possible to perform.

lucky
  • 12,734
  • 4
  • 24
  • 46
  • I'm using Firstclass like this typeof(FirstClass) on GetFoo function. So in FirstClass, FooList variable List seems default Foo class type. @Rainman – Muhammet Can TONBUL Dec 12 '17 at 08:38
  • It could be better to look at this article. You want to deserialize xml by dynamic. https://stackoverflow.com/questions/13704752/deserialize-xml-to-object-using-dynamic – lucky Dec 12 '17 at 10:37