user3970044
user3970044

Reputation:

Setting properties on a class at runtime

I am trying to achieve something like this in C#:

public class GenericModel
{
  public SetPropertiesFromDataRow(DataColumnCollection columns, DataRow row)
  {
    foreach(DataColumn column in columns)
    {
      this.SetProperty(column.ColumnName, row[column.ColumnName]);
    }
  }
}

DataTable students = ReadStudentsFromDatabase(); // This reads all the students from the database and returns a DataTable

var firstStudent = new GenericModel();
firstStudent.SetPropertiesFromDataRow(students.Columns, students.Rows[0]);

Is this possible to do in C# (since it is a static language)?
(Note that this example is somekind of psudocode.)

Upvotes: 0

Views: 724

Answers (4)

Lokesh
Lokesh

Reputation: 129

Use dynamic variables for setting the dynamic property as below:

class Program{
   static void Main(string[] args)
    {
        dynamic x = new GenericModel();
        x.First = "Robert";
        x.Last = " Pasta";

        Console.Write(x.First + x.Last);
    }
  }

class GenericModel : DynamicObject
{
    Dictionary<string, object> _collection = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _collection.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _collection.Add(binder.Name, value);
        return true;
    }
}

Please refer to the link: MSDN

Upvotes: 0

varsha
varsha

Reputation: 1620

You can use Reflection to do this e.g.

objName.GetType().GetProperty("nameOfProperty").SetValue(objName, objValue, null)

Upvotes: 0

opewix
opewix

Reputation: 5083

Here is example of using ExpandoObject

dynamic eo = new ExpandoObject();
var dic = eo as IDictionary<string, object>;
foreach (string propertyName in XXX)
{
    dic[propertyName] = propertyValue;
}

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

Absolutely, this is possible. C# has reflection system that lets you examine class structure and set class elements at runtime. For example, to set a property on this when all you have is a name in a string can be done as follows:

foreach(DataColumn column in columns) {
    PropertyInfo prop = GetType().GetProperty(column.Name);
    prop.SetValue(this, row[column.Name]);
}

This assumes several things:

  • Names of the DataColumn objects exactly match names of properties in your class, including capitalization
  • None of the DataColumns is missing in the type, i.e. if there is a column Xyz there must be a property Xyz in the class
  • Data types of objects you read from the data table are assignment-compatible with the types of their corresponding properties.

If any of these requirements is broken, there will be runtime errors. You can address them in code. For example, if you wish to make it work in situations when generic model might be missing some properties, add a null check on the prop variable, and skip the call to SetValue when you see prop ==null.

Upvotes: 0

Related Questions