Search code examples
c#dynamicgeneric-programming

Dynamically generate object field of generic type


Code:

objectType request = factory.create<objectType>();

public class factory
{
    public static T create<T>() where T : new()
    {
      T obj = new T();
      PropertyInfo propertyInfo = obj.GetType().GetProperty("client_no");
      propertyInfo.SetValue(obj, CLIENT_NUMBER, null);
      return (T)Convert.ChangeType(obj, typeof(T));
     }
}

Explanation:

I am creating a generic factory fn() that sets 2 object properties.

These properties are consistent throughout all the objects I am wanting to initialize.

1) How I call my function

objectType request = factory.create<objectType>(); // <-- This works

1b) From here if I wanted, I could do the following, but is extra code that is repetitive throughout all my objects

request.client_no = CLIENT_NUMBER;

2) Below is my factory fn()

public static T create<T>() where T : new()
{
  T obj = new T();      

  // Here is where I am having trouble setting client_no I will explain in #3         

  return (T)Convert.ChangeType(obj, typeof(T)); // <-- This works returns generic type
}

3) I have tried PropertyInfo to set the object properties as follows

PropertyInfo propertyInfo = obj.GetType().GetProperty("client_no");
propertyInfo.SetValue(obj, CLIENT_NUMBER, null);

I have also tried this

obj.GetType().GetProperty("client_no").SetValue(obj, CLIENT_NUMBER, null); 

And I have tried

T obj = new T();      
var t = typeof(T);
var prop = t.GetProperty("client_no");
prop.SetValue(obj, CLIENT_NUMBER);

4) Here is the error that I am receiving

Object reference not set to an instance of an object

More/Newer information:

So with further research. The 3rd party objects properties do not have getters and setters {get; set;} which is why the GetType() & SetValue() do not work.

My co-worker pointed out that the property is a single assignment which is why we can do

request.client_no = CLIENT_NUMBER;

So my question is how do I set these properties?


Solution

  • SOLVED. Here's how.

    My main issue was a miss-understanding, The item I was trying to set was not a property, but rather a field.

    To better understand the difference yourself you can check out this.

    Here is how I fixed it:

    I set the field types of the generic

    public static T create<T>() where T : new()
    {
      T obj = new T();
    
      Type myType = typeof(T);
      FieldInfo myFieldInfo = myType.GetField("client_no");
      myFieldInfo.SetValue(obj, CLIENT_NUMBER);                        
    
      return obj;
    }
    

    Special thanks to @MattBurland which led me in the right direction.