Reputation: 143
I have a lot of model classes that I fill in with data from API.
Structure of API data is DataRow.
For each class there is an implicit conversion from DataRow to model class.
I have to write a set of functions for each model class. One of the functions, get from database, is common for all model classes so I decided to write function with generic type for this.
Here is an example of model class:
public class Person
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public static implicit operator Person(DataRow dataRow)
{
if (dataRow != null)
{
return new Person
{
Id = long.Parse((string)dataRow["Id"]),
FirstName = (string)dataRow["FirstName"],
LastName = (string)dataRow["LastName"]
};
};
return null;
}
}
example of class with generic type for casting, looks like this:
public class DefaultRepository<T>
{
public T CreateInstanceOfModelFromDataRow(DataRow dataRow)
{
T modelInstance = (T)Activator.CreateInstance(typeof(T));
modelInstance = (T)dataRow;
return modelInstance;
}
}
and code for testing looks like this:
// for testing I will create DataTable and DataRow and populate it fake data
DataTable fakeTable = new DataTable();
fakeTable.Columns.Add("Id");
fakeTable.Columns.Add("FirstName");
fakeTable.Columns.Add("LastName");
DataRow fakeRow = fakeTable.NewRow();
fakeRow["Id"] = "1";
fakeRow["FirstName"] = "John";
fakeRow["LastName"] = "Doe";
// Cast DataRow to Pesron without error
Person fakePerson01 = (Person)fakeRow;
// Cant cast on this way create error while compiling
DefaultRepository<Person> defRepo = new DefaultRepository<Person>();
Person fakePerson02 = defRepo.CreateInstanceOfModelFromDataRow(fakeRow);
I get error while compiling "Cannot convert type 'System.Data.DataRow' to 'T'" at line modelInstance = (T)dataRow;
I try with (T)Convert.ChangeType(dataRow, typeof(T));
also but no luck.
Is it posible to do this conversion?
Upvotes: 1
Views: 1589
Reputation: 2540
Since you are using generics, compiler does not know what type T
is, hence you are getting the compile time error.
You will need to add constraint to your generic implementation -
public class DefaultRepository<T> where T : Person
{
public T CreateInstanceOfModelFromDataRow(DataRow dataRow)
{
T modelInstance = (T)Activator.CreateInstance(typeof(T));
modelInstance = (T)dataRow;
return modelInstance;
}
}
Also you need not create instance through reflection. You can just cast dataRow to your class -
public class DefaultRepository<T> where T : Person
{
public T CreateInstanceOfModelFromDataRow(DataRow dataRow)
{
var modelInstance = (T)dataRow;
return modelInstance;
}
}
Upvotes: 1