0

I have a class called CoverageBase with properties say A, B, C. And now based on some checks i need to append n number of properties say D and E properties in to this CoverageBase class along with my existing A, B, C. So for creating D and E dynamically during the runtime i am using Dictionary

class CoverageBase
{
   public string A { get; set; }
   public string B { get; set; }
   public string C { get; set; }
}

Dictionary<string, object> values = new Dictionary<string, object>()
{
  {"D",5},{"E",123}
};

var test = GetObject<CoverageBase>(values);

T GetObject<T>(Dictionary<string,object> dict)
{
  Type type = typeof(T);
  var obj = Activator.CreateInstance(type);

  foreach (var kv in dict)
  {
    type.GetProperty(kv.Key).SetValue(obj, kv.Value);
  }
  return (T)obj;
}

The problem with above approach is, when i try to GetProperty using "D" there will not be any property existing in that name in the CoverageBase class right. so it will throw error. So how do i build my expected class with properties A, B, C, D, E

Can we use any of the existing tools like ExpandoObject or DynamicObject for this?

Nithin Paul
  • 2,169
  • 3
  • 33
  • 55
  • 1
    You just can't add new properties to existing class. – Evk Feb 19 '18 at 06:40
  • 2
    @Evk can't we use any of the existing tools like ExpandoObject or DynamicObject for that? – Nithin Paul Feb 19 '18 at 06:42
  • Nope. Your `CoverageBase` has static set of 3 properties and there is no way to add or remove anything from it at runtime. You can generate new class at runtime which inherits from `CoverageBase` and adds those properties, but that's about it. – Evk Feb 19 '18 at 06:45
  • @Evk can you elaborate little bit more about inheriting it. Because these new properties is not existing in my CoverageBase class right. So in that case how do i extend my properties and later re use it? – Nithin Paul Feb 19 '18 at 06:54
  • 2
    As usual, it's better to describe _why_ you need this, because there is very high chance that you actually don't and your problem can be solved in a better way. As for inheriting at runtime - that's not trivial but there are libraries for that, such as https://github.com/ekonbenefits/impromptu-interface (well it can implement interface at runtime but that's similar). – Evk Feb 19 '18 at 06:59
  • @Evk The requirement is, i have a service which is consumed by many coverages. Every coverages will have some common properties and some coverage specific properties. So based on coverages selected i need to build class with common properties and coverage specific properties. – Nithin Paul Feb 19 '18 at 07:15
  • 1
    Then maybe just add property of type Dictionary to base coverage class and store additional properties there? – Evk Feb 19 '18 at 07:27
  • how your object is consumed? I mean you transfer a json or xml or whatever else into remote services? if so you can just serialize your data properly (see example here: https://stackoverflow.com/questions/22105722/serializing-an-object-containing-a-dictionary-such-that-the-dictionary-keys-valu or https://www.newtonsoft.com/json/help/html/SerializeDictionary.htm) – Igor Gnedysh Feb 19 '18 at 08:08
  • `So based on coverages selected i need to build class with common properties and coverage specific properties.` Why specifically are you trying to solve this using a _single_ class? Why not use inheritance? As a general rule of thumb, the application's input data should never decide the application's data structure. Instead, you should _construct_ your data structure to suit the expected input data. Not the other way around. – Flater Feb 19 '18 at 09:08

1 Answers1

0

The important thing to remember with C# and other .Net based languages is the difference between strongly typed classes and non-strongly typed classes. In practice, Dynamics (non-strongly typed) are generally considered the lazy mans approach to rapid development. It is not advised to use Dynamics as a catch all approach unless you really need to.

There are ways to accomplish what you are going for, however, it would end up having to use dynamics at run time for when you want to interact with your class.

What you should look at is Newtonsoft.Json. Using Json, you can convert a C# Class into a JObject and then manipulate it as if it were a Dictionary. This will allow you to append extra fields and properties, but not methods. When you are finished modifying your object, you can convert it back to a dynamic and then interact with it as a normal expando object.

If you really want to create a strongly typed class at runtime, then you would need to look into runtime compilation. This would use the C# CodeDom provider and allows you to compile 'text' into C Sharp assemblies which contain one or more types. Those types can be anything that compiles successfully from your provided text input.

Baaleos
  • 1,703
  • 12
  • 22