Скопировать массив объектов в массив другого типа

StackOverflow https://stackoverflow.com/questions/679031

  •  21-08-2019
  •  | 
  •  

Вопрос

Ранее я столкнулся с проблемой при попытке совместного использования определения типа между моим веб-сервисом ASMX и моей страницей .aspx (веб-клиентом).

Запутался в C#: Массив объектов и неявное преобразование типов

Насколько я понимаю совет, «проблему», которую это создает, можно решить путем копирования массива объектов, созданного в клиенте, в новый массив объектов, определенный прокси-классом ASMX.

Будучи новичком в C#, я все еще пытаюсь справиться с этой простой задачей.Вот еще части моего кода (остальные фрагменты в предыдущем посте остались неизменными):

...здесь я заполняю «тестовые данные», которые хочу передать веб-сервису:

// create an array of MetaData objects
MetaData[] nvPairs = new MetaData[20];   // arbitrary length of 20 pairs

// create arbitrary MetaData objects in the array
nvPairs[0] = new MetaData("Grant Number", "2577-9912");
nvPairs[1] = new MetaData("OPEAnalyst", "Simpson");

...здесь я пытаюсь функцию «скопировать» из «реального» типа, определенного в моем пространстве имен TRIMBrokerUtil (которое я не могу использовать полностью из-за прокси-сервера), в прокси-версию этого типа:

protected TRIMBrokerASMXProxy.ASMXProxy.MetaData[] CopyMetaData(
    MetaData utilArray)
{
    TRIMBrokerASMXProxy.ASMXProxy.MetaData[] outArray = 
        new TRIMBrokerASMXProxy.ASMXProxy.MetaData[utilArray.Name.Length];
    int i;
    for (i = 0; i < utilArray.Name.Length; i++)
    {
        outArray[i].Name = utilArray.Name;
        outArray[i].Value = utilArray.Value;
    }
    return outArray;
}

...и вот здесь я пытаюсь вызвать эту функцию (компилятор отмечает 2 ошибки в этой строке:

TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData = 
    CopyMetaData(metaDataArray); 

Обе ошибки компиляции ниже указывают на одну и ту же строку:

Ошибка 1. Лучшее совпадение перегруженного метода для «_Default.CopyMetaData(TRIMBrokerUtil.MetaData)» имеет несколько недопустимых аргументов.

Ошибка 2. Аргумент «1»:невозможно преобразовать «TRIMBrokerUtil.MetaData[]» в «TRIMBrokerUtil.MetaData»

Я близко?

Это было полезно?

Решение

Вы объявили свой параметр как MetaData скорее, чем MetaData[] - другими словами, это не массив.Затем вы используете utilArray.Name довольно много, но непонятно почему.

Я подозреваю, что вы действительно хотите:

protected TRIMBrokerASMXProxy.ASMXProxy.MetaData[]
    CopyMetaData(MetaData[] utilArray)
{
    TRIMBrokerASMXProxy.ASMXProxy.MetaData[] outArray = 
        new TRIMBrokerASMXProxy.ASMXProxy.MetaData[utilArray.Length];
    for (int i = 0; i < utilArray.Length; i++)
    {
        outArray[i] = new TRIMBrokerASMXProxy.ASMXProxy.MetaData();
        outArray[i].Name = utilArray[i].Name;
        outArray[i].Value = utilArray[i].Value;
    }
    return outArray;
}

Кстати, возможно, вы захотите рассмотреть using директива, чтобы облегчить чтение:

using ProxyMetaData = TRIMBrokerASMXProxy.ASMXProxy.MetaData;

...

protected ProxyMetaData[] CopyMetaData(MetaData[] utilArray)
{
    ProxyMetaData[] outArray = new ProxyMetaData[utilArray.Length];
    for (int i = 0; i < utilArray.Length; i++)
    {
        outArray[i] = new ProxyMetaData();
        outArray[i].Name = utilArray[i].Name;
        outArray[i].Value = utilArray[i].Value;
    }
    return outArray;
}

Другой альтернативой является Array.ConvertAll:

ProxyMetaData[] output = Array.ConvertAll(input,
    metaData => new ProxyMetaData(metaData.Name, metaData.Value));

Если вы не используете C# 3, вы можете использовать для этого анонимный метод.Если ProxyMetaData нет соответствующего конструктора, и вы являются используя С# 3, вы можете использовать инициализатор объекта:

ProxyMetaData[] output = Array.ConvertAll(input,
    metaData => new ProxyMetaData { metaData.Name, metaData.Value });

Если вы застряли на C# 2 и у вас нет подходящего конструктора, то:

ProxyMetaData[] output = Array.ConvertAll(input, delegate(MetaData metaData)
{
    ProxyMetaData proxy = new ProxyMetaData();
    proxy.Name = metaData.Name;
    proxy.Value = metaData.Value;
});

я думать это охватило все основы :)

Другие советы

Я бы просто использовал LINQ для этого:

TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData =
    metaDataArray.Select(d => 
        new TRIMBrokerASMXProxy.ASMXProxy.MetaData(
            d.Name, d.Value)).ToArray();

Кроме того, если вы используете .NET 3.5, это означает, что вы также можете использовать WCF, который вам следует использовать для создания прокси.Вы сможете присвоить тип TRIMBrokerASMXProxy.ASMXProxy.MetaData атрибуту DataContract, а сериализуемые элементы — атрибуту DataMember.Тогда вы сможете определить свой контракт с фактическим типом, и вам вообще не придется выполнять преобразование.

Вы также можете использовать Array.ConvertAll.Я знаю, что вы относительно новичок в этом, поэтому позвольте мне попытаться объяснить.Он имеет 2 общих параметра.Первый — это тип массива, который он хочет преобразовать (назовем его I).И второй тип, в который вы хотите преобразовать (назовем его O).Он принимает массив типа I и возвращает массив типа O.Второй параметр — делегат Converter.Применяя именование, мы получаем его подпись.

delegate O Converter(I input);

Тело делегата должно содержать код, необходимый для преобразования.Внутри функции ConvertAll код перебирает каждое значение входного массива и затем передает его делегату.Значение, возвращаемое делегатом, затем сохраняется в выходном массиве.Выходной массив возвращается пользователю после преобразования всех значений.

using ProxyMetaData = TRIMBrokerASMXProxy.ASMXProxy.MetaData;

ProxyMetaData[] convertedArray = Array.ConvertAll<MetaData, ProxyMetaData>(utilArray, 
delegate(MetaData metaData)
{
    ProxyMetaData returnValue = new ProxyMetaData();
    returnValue.Name = metaData.Name;
    returnValue.Value = metaData.Value;
    return returnValue;
});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top