C# Type Conversion
Вопрос
У меня есть два объекта. Объект A и объект B.
Объект A является экземпляром класса, который был сгенерирован из нескольких файлов XSD. Использовал XSD.Exe /C и составил их. Теперь у меня есть мой новый объект.
У меня также есть веб -сервис, возвращая что -то очень похожее на объект A. Итак, сейчас у меня есть что -то в этом роде:
WebService.foo myResponseObj = MyService.GetObject(inData);
MyFramework.foo myClientObj = new MyFramework.foo();
Я хочу сделать это
myClientObj = (MyFramework.foo)myResponseObj
Тем не менее, это не очень нравится это. Говорит "не может неявно преобразовать myframework.foo [] webservice.foo [
Есть идеи о том, как это решить? Объект довольно большой, и они в основном идентичны.
Решение
Как насчет извлечения интерфейса (щелкните правой кнопкой мыши на один класс, выберите Refactor-> Извлечь интерфейс) и примените этот интерфейс к обоим классам?
Так что это будет выглядеть как:
namespace WebService
{
public class foo : IExtractedInterface
}
а также
namespace MyFramework
{
public class foo : IExtractedInterface
}
Тогда вы должны иметь возможность сделать:
IExtractedInterface myClientObj = (IExtractedInterface)myResponseObj;
Другие советы
Оба объекта должны были бы унаследовать от одного и того же интерфейса, чтобы успешно выполнить указанный вами состав. Вы можете посмотреть на выявление общего метода (и), который вам нужен, в интерфейс, который может быть реализован в обоих классах, так что вы можете просто поднять на тип интерфейса, а затем иметь доступ только к этим методам, а не на весь объект.
Наслаждаться!
Вам нужно сделать метод, который преобразует один класс в другой, вручную копировав все свойства.
Затем вы можете вызвать этот метод в Array.ConvertAll
.
Они «в основном идентичны» недостаточны. Вы можете разыгнуть только между двумя объектами, если они совместимы с типом, что означает, что они имеют общий потомок, и фактические типы действительны для кастинга.
Например, следующее работает, если Circle
это потомка Shape
:
Shape x = new Circle();
Circle y = (Circle)x;
Однако следующее завещание нет рабочее событие, если ClassA
а также ClassB
иметь одинаковые поля, но на самом деле не произошли друг от друга:
ClassA a = new ClassA();
ClassB b = (ClassA)a;
Может быть, стоит заставить их оба реализовать общий интерфейс, затем вы можете поднять на этот интерфейс и использовать их так, как вы хотите.
Это в основном ответил уже. Анкет Обратите внимание, однако, что в дополнение к тому, что здесь ответили, существует небольшой проблеск надежды, предоставленного новой функцией .NET 4 «эквивалентность типа»:
Однако обратите внимание, что C# 4 будет поддерживать ограниченную форму структурного типирования на интерфейсах. Видеть http://blogs.msdn.com/samng/archive/2010/01/24/the-pain-of-deploying-primary-interop-assemblies.aspx Для деталей.
Это довольно продвинутый .net-foo, хотя.
Если вы используете стандартный инструмент 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;
Если это массив, который предлагает вам предложенная цитата, то вы должны выполнять итерацию через сбор ответов и добавить объекты участников в коллекцию клиентов.