views:

122

answers:

7

Hi guys, I have two objects. Object A and Object B.

Object A is an instance of a class that was generated from several XSD files. Used xsd.exe /c and compiled them. Now I have my new object.

I also have a web service, returning something very similar to object A. So right now I have something along the lines of this:

WebService.foo myResponseObj = MyService.GetObject(inData);
MyFramework.foo myClientObj = new MyFramework.foo();

What I want to do is this

myClientObj = (MyFramework.foo)myResponseObj

However, it's not really liking this. Says "Cannot implicitly convert MyFramework.foo[] to WebService.foo[]

Any ideas on how to resolve this? The object is quite large and they are basically identical.

+1  A: 

You need to make a method that converts one class into the other by manually copying all of the properties.

You can then call that method in Array.ConvertAll.

SLaks
That's what I was afraid of / was hoping to avoid. Thanks
PSU_Kardi
+3  A: 

Hi,

Both objects would need to inherit from the same interface in order to successfully perform the cast you have specified. You might look at pulling out the common method(s) you need into an interface that can be implemented in both classes, that way you can just cast to the interface type and then have access to just those methods rather than the entire object.

Enjoy!

Doug
+3  A: 

How about extracting the interface (right click on one class, select Refactor->Extract Interface), and apply this interface to both classes?

So it will look something like:

namespace WebService
{
   public class foo : IExtractedInterface
}

and

namespace MyFramework
{
   public class foo : IExtractedInterface
}

You should then be able to do:

IExtractedInterface myClientObj = (IExtractedInterface)myResponseObj;
code4life
+1  A: 

Them being "basically identical" is insufficient. You can only cast between two objects if they are type-compatible, meaning that they share a common descendant and the actual types are valid for casting.

For example, the following works if Circle is a descendant of Shape:

Shape x = new Circle();
Circle y = (Circle)x;

However, the following will not work event if ClassA and ClassB have the exact same fields but are not actually descended from each other:

ClassA a = new ClassA();
ClassB b = (ClassA)a;

It may be worthwhile to make them both implement a common interface, then you could cast to that interface and use them the way you want.

Donnie
A: 

If it is an array, which the quote you gave suggests, then you have to iterate through the response collection and add the member objects into the client collection.

Caleb Thompson
+1  A: 

This has basically been answered already. Note, however, that in addition to what's been answered here, there is a small glimmer of hope provided by .NET 4's new "Type Equivalence" feature:

Note however that C# 4 will support a limited form of structural typing on interfaces. See http://blogs.msdn.com/samng/archive/2010/01/24/the-pain-of-deploying-primary-interop-assemblies.aspx for details.

This is pretty advanced .NET-foo, though.

hemp
+1  A: 

If you're using the standard wsdl.exe tool to create your proxy and supporting classes, then I believe it generates the code as partial classes. If that is your situation, then you could insert your own implicit conversion operator to one of the types. For instance, let's say you have your MyService.foo class defined in the file "MyService\foo.cs" as below:

namespace MyService
{
    public partial class foo
    {
        public string PropertyA { get; set; }
        public string PropertyB { get; set; }
        public string PropertyC { get; set; }
        // ...
    }
}

And you have your MyFramework.foo class defined in the file "MyFramework\foo.cs" as below:

namespace MyFramework
{
    public class foo
    {
        public string PropertyA { get; set; }
        public string PropertyB { get; set; }
        public string PropertyC { get; set; }
        // ...
    }
}

Then you can create a separate file, let's say "MyService\foo.conversion.cs" as below:

namespace MyService
{
    partial class foo
    {
        public static implicit operator MyFramework.foo(foo input)
        {
            return new MyFramework.foo
            {
                PropertyA = input.PropertyA,
                PropertyB = input.PropertyB,
                PropertyC = input.PropertyC,
                // ...
            };
        }
    }
}

And that would allow you to write most of your code using a MyService.foo object as if it were a MyFramework.foo object. The following code compiles with the above setup:

        MyService.foo x = new MyService.foo();

        MyFramework.foo y = x;
Dr. Wily's Apprentice