Отражение — установка типа возвращаемого объекта?
-
05-09-2019 - |
Вопрос
Я заполняю объекты разных типов строками данных с каждым атрибутом соответствующего объекта = аналогичному полю имени в строке данных.
Для этого я хотел бы использовать общую функцию.Как принудительно указать тип возвращаемого объекта из универсальной функции.Я еще не знаю, что <T>
синтаксис на самом деле означает: PopulateObject<T>
не возвращает тип, когда я получаю ошибку компилятора - не может неявно преобразовать тип «объект» в «jobCard», см. мой код ниже
public JobCard AcceptJobCard(Guid jobCardGuid, Guid userGuid)
{
try
{
JobCard jc= new JobCard();
DL_ISMS.DataSets.JobCardDS.View_JobcardDataTable dtJC = BL_ISMS.Meter.JobCard_CB.FetchJobCard(jobCardGuid);
DL_ISMS.DataSets.JobCardDS.View_JobcardRow jcRow = dtJC[0];
DateTime dateAccept = DateTime.Now;
bool res = BL_ISMS.Meter.JobCard_CB.UpdatePdaJobCard(userGuid, jobCardGuid, null, null, null, JobCardStatus.Accepted.GetHashCode(), null, null, null, null, "", "", "", "", "", "", null, dateAccept, null, null, null, null, null, null);
if (res)
{
jc = PopulateObject<JobCard>(jc, jcRow);
return jc;
}
else
return jc;
}
catch (Exception ex )
{
Trace.WriteException(ex);
throw;
}
}
private object PopulateObject<T>(object dataObj, System.Data.DataRow dataRow)
{
Type type = dataObj.GetType();
System.Reflection.PropertyInfo[] proplist = type.GetProperties();
string s = "";
foreach ( System.Reflection.PropertyInfo propertyitem in proplist)
{
s += propertyitem.Name + ":" + (propertyitem.GetValue(dataObj,null)).ToString() + "\r\n";
propertyitem.SetValue(dataObj, dataRow["propertyitem.Name"], null);
}
return (T)dataObj;
}
----обновлено после второго ответа----
используя этот код:private t opulateObject (t dataObj, system.data.datarow dataRow) {
System.Reflection.PropertyInfo[] proplist = dataObj.GetType().GetProperties();
foreach ( System.Reflection.PropertyInfo propertyitem in proplist)
{
if(propertyitem.Name != "")
try
{
propertyitem.SetValue(dataObj, dataRow[propertyitem.Name], null);
}
catch (Exception ex)
{
if (ex.Message.Contains("does not belong to table"))
{
propertyitem.SetValue(dataObj, PopulateObject<propertyitem.GetType()>(propertyitem, dataRow), null);
}
else
throw;
}
}
return dataObj;
}
Однако я столкнулся с еще одним препятствием.Один из атрибутов на самом деле является другим объектом, называемым Customer, с 11 собственными атрибутами.Я подозреваю, что еще скрываются еще несколько вложенных объектов.Как мне справиться с заполнением этих вложенных объектов, для которых в строке данных есть только одно поле?
Для обработки этих объектов:- Мне придется извлечь тип ChildOBJ в родительский objdata - вызовать функцию ProcessChildObj (), к которой я передаю childObjtype, и полный DataRow - и в ProcessChildObj () Сделайте сочетание имени и устанавливаю этот атрибут?
или (как в коде выше) - вызовите opulateObject рекурсивно.Однако это создает у меня проблему, поскольку компилятор жалуется, когда я пытаюсь передать тип obj в рекурсивный вызов:
propertyitem.SetValue(dataObj, PopulateObject(propertyitem, dataRow), null);// вызывает сообщение компилятора "Оператор '<' не может быть применен к операндам типа 'группа методов' и 'System.type'"
Как извлечь тип вложенного дочернего объекта, чтобы передать его в качестве параметра?
Решение
Измените подпись вашего метода на:
private T PopulateObject<T>(T dataObj, System.Data.DataRow dataRow)
Кроме того, я думаю, вам не нужно возвращать какой-либо объект, поскольку вы обновляете только существующий объект.Вы можете просто использовать:
private void PopulateObject(object dataObj, System.Data.DataRow dataRow)
Другие советы
Возвращаем его... почему верни это?Вы уже обновили его...вызывающий абонент увидит изменение.И если вы не используете дженерики в методе (вы этого не делаете), просто используйте object
и никаких дженериков.
Если сам код не работает, я думаю, что самая большая проблема заключается в использовании нить "propertyitem.Name", вместо оценки значения свойства: propertyitem.Name
:
propertyitem.SetValue(dataObj, dataRow[propertyitem.Name], null); // no quotes
Возможно, вы захотите посмотреть эта почта слишком.