Reflection - setting Type of returned obj?

こ雲淡風輕ζ 提交于 2019-12-11 05:03:01

问题


I am populating different types objects with datarows with each attrivute of the relevant object = to the similiarly name field in the datarow.

I'd like to use a generic function to do this. How do I force the Type of the return object from the generic function. I don't yet know what the <T> syntax actually means: PopulateObject<T> does not return the type as I get compiler error - Cannot implicitly convert type 'object' to 'JobCard' See my code below

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;
}

----updated after 2nd answer----

using this code: private T PopulateObject(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;
}

I have hit another roadblock though. One of the attributes is actually another object called Customer, with 11 attributes of it's own. I suspect there even are more nested objects still lurking. How would I handle the populating of these nested objects, for whom there is only 1 field in the datarow?.

To handle these objects: - I'd have to extract the ChildObj type in the parent Objdata - call a ProcessChildObj() function to which I pass the ChildObjType, and the complete datarow - and in ProcessChildObj() do a name match, and set that attribute?

or (as in the code above) - Call the PopulateObject recursively. This however presents me with a problem as the compiler complains where I try to pass the obj type into the recursive call:

propertyitem.SetValue(dataObj, PopulateObject(propertyitem, dataRow), null); //causes compiler msg "Operator '<' cannot be applied to operands of type 'method group' and 'System.type'"

How do I extract the type of the nested childObj to pass the type as a parameter?


回答1:


Change your method's signature to:

private T PopulateObject<T>(T dataObj, System.Data.DataRow dataRow)

Also, I think you don't need to return any object because your only updating an existing object. You can just use:

private void PopulateObject(object dataObj, System.Data.DataRow dataRow)



回答2:


Re returning it... why return it? You've already updated it... the caller will see the change. And if you aren't using generics in the method (you aren't) just use object and no generics.

If the code itself doesn't work, I think the biggest problem is using the string "propertyitem.Name", rather than evaluating the property value: propertyitem.Name:

propertyitem.SetValue(dataObj, dataRow[propertyitem.Name], null); // no quotes

You may want to look at this post too.



来源:https://stackoverflow.com/questions/906327/reflection-setting-type-of-returned-obj

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!