Click to See Complete Forum and Search --> : List<object> WCF Method


hoagers34
December 8th, 2008, 10:33 AM
I have a method within my WCF Service that looks like so:

void FooMethod(ref List<object> o)


I have 2 classes that could potentially be put in the list (either or...not both at the same time). I have other parameters that are passed into FooMethod that determine what class to put in the list.

o = new List<ClassA>
-OR-
o = new List<ClassB>

When the client calls the method, the service works fine and returns back, but the client blows up...can you not setup a method that takes a List<object> and convert it to a List<ClassA>? Is there an easier way to accomplish what I am trying to do?

TheCPUWizard
December 8th, 2008, 10:36 AM
When the client calls the method, the service works fine and returns back, but the client blows up...can you not setup a method that takes a List<object> and convert it to a List<ClassA>? Is there an easier way to accomplish what I am trying to do?

Covariant collections are NOT supported. Just because the items within can be cast, does not mean that the collections can be cast [there are MANY very good reasons for this).

hoagers34
December 8th, 2008, 10:52 AM
So would you recommend passing in a string and serializing the list into it and deserializing on the client side?

TheCPUWizard
December 8th, 2008, 10:59 AM
So would you recommend passing in a string and serializing the list into it and deserializing on the client side?

NO. Create overloads that handle the proper collections.

hoagers34
December 8th, 2008, 11:01 AM
I was not aware that you could overload methods in a WCF Service...I know that you cannot in a webservice.

TheCPUWizard
December 8th, 2008, 11:05 AM
I was not aware that you could overload methods in a WCF Service...I know that you cannot in a webservice.

I was being technically sloppy when I used the term "overload". :blush:


void FooMethod_A(ref List<ClassA> o)
void FooMethod_A(ref List<ClassB> o)


Also be aware that ref parameters in WCF serices have some ramifications. The real use-cases for them are fairly rare.

hoagers34
December 8th, 2008, 11:10 AM
I am curious as to why you recommend not using ref?

We use them often in our service methods. Every method we have returns back a custom class (ResponseMessage) with a bool for success, client error description, stack trace and other information if there was an error).

If other items need to be returned, we simply pass it into the method with a 'ref' identifier. What would be the ramifications of doing so? Why would you do it differently?

TheCPUWizard
December 8th, 2008, 11:29 AM
I am curious as to why you recommend not using ref?

We use them often in our service methods. Every method we have returns back a custom class (ResponseMessage) with a bool for success, client error description, stack trace and other information if there was an error).

If other items need to be returned, we simply pass it into the method with a 'ref' identifier. What would be the ramifications of doing so? Why would you do it differently?

The "issue" is that the content has to be passed in BOTH directions. If you are actually returning information, you can take a hige performance hit if the caller accidentally passes in large content:

List<ClassA> data;
for (int i=0; i<100;++i)
{
if (Service.Foo(ref data))
{
// Process data
}


The design pattern I recommend to clients (as a general solution, there are always exceptions) is to use a UNIQUE pair of Resuest/Response classes for Each Method.

By deriving from a common set of bases(interfaces or abstracts), duplication is eliminated, and consistancy enforced.

You can achieve the same type of syntax with a simple helper function that checks a base result boolean field.

boudino
December 9th, 2008, 07:00 AM
Just small correction, to implement overloading in WCF, methods must differ also in names, not only in parameters, because as WCF service, you cannot what the other side of communication is and whether it support overloading or not.

So it should be:

void FooMethod_A(ref List<ClassA> o)
void FooMethod_B(ref List<ClassB> o)


or you can do it on the contract level with OperationContractAttribute (which I personaly would prefere).


[OperationContract(Name="FooMethod_A")]
void FooMethod(ref List<ClassA> o)

[OperationContract(Name="FooMethod_B")]
void FooMethod(ref List<ClassB> o)