将对象数组复制到不同类型的数组

时间:2009-03-24 20:03:44

标签: c# arrays object copying

以前,我遇到了一个问题,试图在我的ASMX webservice和我的.aspx页面(webclient)之间共享一个类型定义

Confused on C# Array of objects and implicit type conversion

据我所知,这个创建的“问题”可以通过将客户端中创建的对象数组复制到ASMX代理类定义的新对象数组来解决。

作为C#的新秀,我仍在努力完成这项简单的任务。以下是我的代码的更多部分(上一篇文章中的其他片段保持不变):

...这里是我填写我要传递给Web服务的“测试数据”的地方:

// 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 个答案:

答案 0 :(得分:7)

您已将参数声明为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;
});

认为涵盖了所有基础:)

答案 1 :(得分:3)

我只想用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属性序列化的成员属性化。然后,您将能够使用实际类型定义合同,而不必执行转换。

答案 2 :(得分:0)

您也可以使用Array.ConvertAll。我知道你对此比较陌生,所以让我试着解释一下。它有2个通用参数。第一个是它想要转换的数组的类型(让我称之为)。第二个是你要转换的类型(让我们称之为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;
});