views:

372

answers:

2

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  A: 

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)
bruno conde
A: 

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.

Marc Gravell
you are right, I spotted that when I ran the code. Is working sort of now.
callisto