Generic List class property

P

phancey

I want to define a class like this

[DataContract]
class MyClass
{
[DataMember]
List<T> MyList<T> where T : IMyList {get; set;}
}

or something like this. I don't want to put <T> on my class definition
because it is only after the instance has been created that I will
know exactly which type of object MyList will use. And I want the
DataContractSerializer to serialize the object straightforwardly so I
want it to remain a Property rather than a method.

But I can't seem to declare it like this. I have tried a few
variations. Is there a solution that is simple or is it not possible?

thanks
Phil
 
M

Marc Gravell

types can be generic, and methods can be generic - however, fields and
properties can only use what the type defines. In short, this would
have to be a MyClass<T> to do what you want, or would have to use a
non-generic list interface such as IList - or settle for a fixed
List<somebasetype>. What exactly is the context - i.e. what are you
trying to model? there may be better approaches...

Marc Gravell
[C# MVP]
 
P

phancey

types can be generic, and methods can be generic - however, fields and
properties can only use what the type defines. In short, this would
have to be a MyClass<T> to do what you want, or would have to use a
non-generic list interface such as IList - or settle for a fixed
List<somebasetype>. What exactly is the context - i.e. what are you
trying to model? there may be better approaches...

Marc Gravell
[C# MVP]

i have a Survey object that will hold a static data object and a user
data object.

First I read from the database and populate the survey attributes.
Then I populate the static data object with various lists (these are
basically just records from the static data tables in the db).
One of these lists is a list of Elements but this list could be one of
2 types of business object depending on the type of survey (an
attribute of the survey object). I know that both classes implement
the IElement interface and I want to serialize the object at the end
with whichever list is relevant.

I could create 2 properties (List<Element> Elements and
List<OtherElement> OtherElements), populate the appropriate one and
then use XSL to translate the serialized XML so it only looks like a
single property? But I wondered if there was a neater solution.

thanks for any advice
Phil
 
P

phancey

[...]
One of these lists is a list of Elements but this list could be one of
2 types of business object depending on the type of survey (an
attribute of the survey object). I know that both classes implement
the IElement interface and I want to serialize the object at the end
with whichever list is relevant.

If you don't know at compile time what the type is, then using a generic  
list isn't all that helpful anyway.  At the very least, you might as well  
use List<Object> or an ArrayList instead.

That said, you say that the type will always implement IElement.  So maybe  
it makes sense to make your list simply  List<IElement>.

Whether this will work with your serialization depends on what  
serialization technique you're using.  But my recollection is that the  
built-in serialization uses reflection to figure out what to write out, so  
the static typing of the object shouldn't be an impediment.

Pete

Yes I think you are right. The only trouble is that the way everything
has already been coded in our system makes this very difficult. I
thought I could code as List<IElement> but then kept getting errors
saying that a List<Element> could not be converted to a List<IElement>
because the methods in our existing system return List<concreteclass>.
What I need to do is adapt somehow so that I add concreteclass
instances to the List<IElement> instead of adding them to a
List<Element> and then trying to cast that back as it doesn't work
that way. Trouble is this may be very difficult with the code I have
inherited.

thanks
 
P

phancey

Yes, you're right.  With a List<IElement> everywhere, you can add Element  
instances as well as IElements.  But you can't just go assigning a  
List<Element> to a variable of List<IElement> or vice a versa.  If you  
could, then that would open the door for code that compiles just fine but 
which tries to add list items of the wrong type to the list.

Note that List<T> implements IList, and that interface supports all the  
basic list operations.  That's why Marc suggested using it as the type for  
the variable.

Without the bigger picture, it's hard to know exactly what the right  
advice is.  But it seems like if you can't go back and fix all your code  
so that it's using a more basic data type, or just use IList.  Of course,  
it's also possible that you should just skip the idea of having a  
general-purpose type for the purpose mentioned in your original post.

Pete

thanks. I ended up recoding the other bits around my code so that I
could use a List<IElement> and it would be created as such in the
first place instead of the code only creating List<concreteclass>.

thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top