Копировать массив объектов в массив другого типа - PullRequest
1 голос
/ 24 марта 2009

Ранее я столкнулся с проблемой, пытаясь разделить определение типа между моим веб-сервисом 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»

Я близко?

Ответы [ 3 ]

7 голосов
/ 24 марта 2009

Вы объявили, что ваш параметр 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 не имеет подходящего конструктора и вы используете , используя C # 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;
});

Я думаю , что охватывает все основы:)

3 голосов
/ 24 марта 2009

Я бы просто использовал 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. Тогда вы сможете определить свой контракт с фактическим типом, и вам вообще не придется выполнять конвертацию.

0 голосов
/ 24 марта 2009

Вы также можете использовать 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;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...