Преобразование типов C # - PullRequest
0 голосов
/ 02 июня 2010

У меня есть два объекта. Объект А и Объект Б.

Объект A является экземпляром класса, который был сгенерирован из нескольких файлов XSD. Использовал xsd.exe / c и скомпилировал их. Теперь у меня есть новый объект.

У меня также есть веб-сервис, возвращающий что-то очень похожее на объект А. Так что сейчас у меня есть что-то вроде этого:

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

Что я хочу сделать, это

myClientObj = (MyFramework.foo)myResponseObj

Однако это не очень нравится. Говорит "Не могу неявно преобразовать MyFramework.foo [] в WebService.foo []

Есть идеи, как решить эту проблему? Объект довольно большой, и они в основном идентичны.

Ответы [ 7 ]

3 голосов
/ 02 июня 2010

Как насчет извлечения интерфейса (щелкните правой кнопкой мыши на одном классе, выберите Refactor-> Extract Interface) и примените этот интерфейс к обоим классам?

Так это будет выглядеть примерно так:

namespace WebService
{
   public class foo : IExtractedInterface
}

и

namespace MyFramework
{
   public class foo : IExtractedInterface
}

После этого вы сможете сделать:

IExtractedInterface myClientObj = (IExtractedInterface)myResponseObj;
3 голосов
/ 02 июня 2010

Оба объекта должны наследоваться от одного и того же интерфейса, чтобы успешно выполнить указанное вами приведение. Вы можете посмотреть на извлечение необходимого общего (ых) метода (ов) в интерфейс, который может быть реализован в обоих классах, таким образом, вы можете просто привести к типу интерфейса и затем получить доступ только к этим методам, а не ко всему объекту.

Наслаждайтесь!

1 голос
/ 02 июня 2010

Если вы используете стандартный инструмент wsdl.exe для создания прокси и вспомогательных классов, то я считаю, что он генерирует код как частичные классы.Если это ваша ситуация, то вы можете вставить свой собственный оператор неявного преобразования в один из типов.Например, предположим, что ваш класс MyService.foo определен в файле «MyService \ foo.cs», как показано ниже:

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

И у вас есть класс MyFramework.foo, определенный в файле «MyFramework \»foo.cs "как показано ниже:

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

Затем вы можете создать отдельный файл, скажем," MyService \ foo.conversion.cs ", как показано ниже:

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,
                // ...
            };
        }
    }
}

И это будетпозволяют вам писать большую часть вашего кода, используя объект MyService.foo, как если бы это был объект MyFramework.foo.Следующий код компилируется с вышеуказанной настройкой:

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

        MyFramework.foo y = x;
1 голос
/ 02 июня 2010

Это в основном было уже ответил . Однако обратите внимание, что в дополнение к ответу, приведенному здесь, есть небольшой проблеск надежды, предоставляемый новой функцией «Эквивалентность типов» в .NET 4:

Обратите внимание, что C # 4 будет поддерживать ограниченная форма структурной типизации на интерфейсы. Подробнее см. http://blogs.msdn.com/samng/archive/2010/01/24/the-pain-of-deploying-primary-interop-assemblies.aspx.

Хотя это довольно продвинутый .NET-foo.

1 голос
/ 02 июня 2010

Их «в основном идентично» недостаточно. Вы можете выполнять приведение между двумя объектами только в том случае, если они совместимы по типу, это означает, что они имеют общего потомка, и действительные типы действительны для приведения.

Например, следующее работает, если Circle является потомком Shape:

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

Однако следующее не рабочее событие, если ClassA и ClassB имеют одинаковые поля, но на самом деле не происходят от друг друга:

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

Может быть, стоит сделать так, чтобы они оба реализовали общий интерфейс, тогда вы можете привести их к этому интерфейсу и использовать их так, как хотите.

1 голос
/ 02 июня 2010

Вам нужно создать метод, который преобразует один класс в другой, вручную скопировав все свойства.

Затем вы можете вызвать этот метод в Array.ConvertAll.

0 голосов
/ 02 июня 2010

Если это массив, который указывает приведенная вами цитата, то вам нужно перебрать коллекцию ответов и добавить объекты-члены в коллекцию клиентов.

...