简体   繁体   English

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

[英]Copy array of objects to array of different type

Previously, I ran into a problem trying to share a type definition between my ASMX webservice and my.aspx page (webclient)以前,我在尝试在我的 ASMX webservice 和 my.aspx 页面(webclient)之间共享类型定义时遇到了问题

Confused on C# Array of objects and implicit type conversion 对 C# 对象数组和隐式类型转换感到困惑

As I understand the advice, the "problem" this creates can be solved by copying the array of objects created in the client to a new array of objects as defined by the ASMX proxy class.据我了解,这产生的“问题”可以通过将客户端中创建的对象数组复制到由 ASMX 代理 class 定义的新对象数组来解决。

Being a rookie in C# I am still struggling with this simple task.作为 C# 的新手,我仍在为这个简单的任务而苦苦挣扎。 Here are more parts of my code (the other fragments in the previous post remain unchanged):以下是我的代码的更多部分(上一篇文章中的其他片段保持不变):

... here is where I populate the "test data" I want to pass to the web service: ...这里是我填充“测试数据”的地方,我想传递给 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");

... here I attempt a function to "copy" from "real" type defined in my TRIMBrokerUtil namespace (which I can't use completely because of the proxy) to the proxy version of that type: ...在这里,我尝试使用 function 将我的 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;
}

... and then here is where I try to call that function (compiler flags 2 errors on this line: ...然后在这里我尝试调用 function (编译器在此行标记 2 个错误:

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

Both of the compile errors below point to the same line:下面的两个编译错误都指向同一行:

Error 1 The best overloaded method match for '_Default.CopyMetaData(TRIMBrokerUtil.MetaData)' has some invalid arguments错误 1 '_Default.CopyMetaData(TRIMBrokerUtil.MetaData)' 的最佳重载方法匹配有一些无效的 arguments

Error 2 Argument '1': cannot convert from 'TRIMBrokerUtil.MetaData[]' to 'TRIMBrokerUtil.MetaData'错误 2 参数“1”:无法从“TRIMBrokerUtil.MetaData[]”转换为“TRIMBrokerUtil.MetaData”

Am I close?我接近了吗?

You've declared your parameter to be MetaData rather than MetaData[] - in other words it's not an array.您已将参数声明为MetaData而不是MetaData[] - 换句话说,它不是数组。 You're then using utilArray.Name rather a lot, but it's not clear why.然后,您会大量使用utilArray.Name ,但尚不清楚原因。

I suspect you actually want:我怀疑你实际上想要:

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;
}

By the way, you might want to consider a using directive to make this easier to read:顺便说一句,您可能需要考虑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;
}

Another alternative is Array.ConvertAll :另一种选择是Array.ConvertAll

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

If you're not using C# 3 you can use an anonymous method for that.如果您不使用 C# 3 ,则可以使用匿名方法。 If ProxyMetaData doesn't have an appropriate constructor and you are using C# 3, you can use an object initializer:如果ProxyMetaData没有适当的构造函数并且您使用的C# 3,则可以使用 object 初始化程序:

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

If you're stuck with C# 2 and no appropriate constructor, then:如果您坚持使用 C# 2 并且没有合适的构造函数,那么:

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

I think that's covered all the bases:)认为这涵盖了所有基础:)

I would just use LINQ to do this:我会使用 LINQ 来做到这一点:

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

Additionally, if you are using .NET 3.5, it means you can use WCF as well, which is what you should be using to generate the proxy.此外,如果您使用的是 .NET 3.5,这意味着您也可以使用 WCF,这是您应该用来生成代理的。 You would be able to attribute your TRIMBrokerASMXProxy.ASMXProxy.MetaData type with the DataContract attribute and the members being serialized with the DataMember attribute.您将能够将您的 TRIMBrokerASMXProxy.ASMXProxy.MetaData 类型与 DataContract 属性和被序列化的成员属性与 DataMember 属性。 Then, you would be able to define your contract with the actual type, and not have to perform conversion at all.然后,您将能够使用实际类型定义您的合同,而根本不必执行转换。

You can also use Array.ConvertAll.您也可以使用 Array.ConvertAll。 I know youre relatively new to this so let me try to explain.我知道你对此比较陌生,所以让我试着解释一下。 It has 2 generic parameters.它有 2 个通用参数。 The first one being the type of the array it wants to convert(lets call it I).第一个是它想要转换的数组的类型(我们称之为 I)。 And the second one the type you want to convert to (lets call it O).第二个是您要转换的类型(我们称之为 O)。 It accepts an array of type I and returns an array of type O. The second parameter is a Converter delegate.它接受一个类型为 I 的数组并返回一个类型为 O 的数组。第二个参数是一个 Converter 委托。 Applying the naming we have its signature goes like.应用命名我们有它的签名就像。

delegate O Converter(I input);

The body of the delegate must contain the code necessary to do the conversion.委托主体必须包含进行转换所需的代码。 Inside the ConvertAll function, the code iterates thru each of the values in the input array and passes then to the delegate.在 ConvertAll function 中,代码遍历输入数组中的每个值,然后传递给委托。 The value returned by the delegate is then stored into an output array.然后将委托返回的值存储到 output 数组中。 The output array is returned to the user once all values are converted.转换所有值后,output 数组将返回给用户。

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM