Generics and casting

Last post 07-23-2006 3:55 AM by doormalena. 5 replies.

Sort Posts:

  • Generics and casting

    03-18-2006, 2:28 PM
    • Member
      225 point Member
    • doormalena
    • Member since 03-18-2006, 3:03 PM
    • Posts 45

    I have a xml file with data from various sources. For example:

    <root>
      <Account>
        <Id>1</Id>
        <Name>Somename</Name>
        <City>Somecity</City>
        <ContactPersons>
          <ContactPerson>
            <Id>1</Id>
            <Name>Somename</Name>
          </ContactPerson>
          <ContactPerson>
            <Id>2</Id>
            <Name>Somename2</Name>
          </ContactPerson>
        </ContactPersons>
      </Account>
    </root>

    I created a generic businesscollection (named BusinessCollection) and a business class (named BusinessObject).
    Then I created a specific business class named Account en another one called ContactPerson. They both derive from the BusinessObject class.

    I created a instance of a businesscollection with accounts using:
    BusinessCollection <Account> collection = new BusinessCollection <Account>();

    I also made a parser that 'translates' the xml into the correct business classes. So in case of the data above I
    provide a instance of BusinessCollection <Account>. Then I create Account objects and add them to the collection. This is all done
    using reflection and some XPath classes.

    The parser has the folling method signature:
    public static void ParseToBusinessObjects <T>(BusinessCollection <T> collection, XPathDocument document) where T : BusinessObject

    So far so good. But now I also want subcollections to parse. In the xml data ContactPersons will be my subcollection (property is named the same).
    If my parser detects a subcollection it will get the current instance (using reflection). I then want to call my entry method again for this collection (recursive)

    However when I do this:
    BusinessCollection <BusinessObject> subCollection = (BusinessCollection <BusinessObject>) property.GetValue(instance, null);

    I get a InvalidCastException saying I can't convert between a BusinessCollection<ContactPerson> and a BusinessCollection<BusinessObject>.

    Its the same when I change it to :
    BusinessCollection <T> subCollection = (BusinessCollection <T>) property.GetValue(instance, null);


    I hope someone knows how to solve this because its driving me nuts.

  • Re: Generics and casting

    03-18-2006, 7:54 PM
    • All-Star
      30,698 point All-Star
    • StrongTypes
    • Member since 12-13-2005, 11:21 AM
    • California
    • Posts 6,007
    • ASPInsiders
      Moderator
      TrustedFriends-MVPs

    So far I envision your code looking like this. If not, please post a skeleton of your code.

    using System;
    using System.Xml.XPath;

    public abstract class BusinessObject { }
    public class BusinessCollection<T> where T : BusinessObject
    { }
    public class Account : BusinessObject
    { }
    public class ContactPerson : BusinessObject { }

    public class Parser
    {
       public static void ParseToBusinessObjects<T>(BusinessCollection<T> collection, XPathDocument document) where T : BusinessObject
    { }
    }

    Could you post your code that relates to this line:

    BusinessCollection <BusinessObject> subCollection = (BusinessCollection <BusinessObject>) property.GetValue(instance, null);

    HTH,
    Ryan

  • Re: Generics and casting

    03-19-2006, 3:43 PM
    • Member
      225 point Member
    • doormalena
    • Member since 03-18-2006, 3:03 PM
    • Posts 45
    Thats about right but I already got the answer I was looking for aldough its not what I hoped for. Its not possible yet because generics don't support covariance.

    Only doable using interfaces and in my case thats no an option because of various reasons.

    I solved it by creating an internal class method which expects an object instead of a BusinessCollection<T>. I then call the add(obj): method on the collection using reflection:

    MethodInfo info = collection.GetType().GetMethod("Add");
    object[] paramaters = new object[1];
    paramaters[0] = businessObject;

    info.Invoke(collection, paramaters);

    Its not a very clean solution but it works for now.

    Thnx!
  • Re: Generics and casting

    06-05-2006, 3:58 PM
    • Member
      152 point Member
    • saintperez
    • Member since 02-08-2006, 9:20 PM
    • Boca Raton, FL.
    • Posts 90

    Doormalena, I have been going nuts with this too for almost a week now. I can't believe you can't cast one list to it's base but I believe you've got a work around. I can't use that for my purposes but would like to know what forums you've researched so I can look at as well.

     

    THanks,

    Santiago

    Santiago Perez
    Systems Architect

    Florida's Turnpike Enterprise
  • Re: Generics and casting

    06-06-2006, 10:33 PM
    • Member
      point Member
    • cupid_c
    • Member since 06-06-2006, 10:28 PM
    • Posts 4
  • Re: Generics and casting

    07-23-2006, 3:55 AM
    • Member
      225 point Member
    • doormalena
    • Member since 03-18-2006, 3:03 PM
    • Posts 45
    saintperez:

    Doormalena, I have been going nuts with this too for almost a week now. I can't believe you can't cast one list to it's base but I believe you've got a work around. I can't use that for my purposes but would like to know what forums you've researched so I can look at as well.

     

    THanks,

    Santiago



    Sorry for the late response. Didn't monitor this thread anymore. I used the c# news groups allot because I got more replies over there.

    I btw now changed the above solution to pass on a generic list interface (IList<T>) instead of a custom collection. The list has already a Add method.
Page 1 of 1 (6 items)