Copie matriz de objetos a matriz do tipo diferente
Pergunta
Anteriormente, eu corri para um problema ao tentar compartilhar uma definição de tipo entre o meu webservice ASMX e minha página aspx (webclient)
confuso sobre C # Array de objetos e implícita de tipo conversão
Como eu entendo o conselho, o "problema" isso cria pode ser resolvido copiando a matriz de objetos criados no cliente para uma nova matriz de objetos como definido pela classe de proxy ASMX.
Sendo um novato em C # ainda estou lutando com esta tarefa simples. Aqui estão mais partes do meu código (os outros fragmentos no post anterior permanecem inalterados):
... aqui é onde eu preencher os "dados de teste" Eu quero passar para o serviço 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");
... aqui eu tento uma função para "cópia" do tipo "real" definido na minha namespace TRIMBrokerUtil (que eu não posso usar completamente por causa do proxy) para a versão do proxy desse tipo:
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;
}
... e, em seguida, aqui é onde eu tento chamar essa função (compilador sinalizadores 2 erro nesta linha:
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData =
CopyMetaData(metaDataArray);
Ambos os erros de compilação abaixo apontam para a mesma linha:
Erro 1 O melhor correspondência método sobrecarregado para '_Default.CopyMetaData (TRIMBrokerUtil.MetaData)' tem alguns argumentos inválidos
Erro 2 Argumento '1': não podem converter de 'TRIMBrokerUtil.MetaData []' para 'TRIMBrokerUtil.MetaData'
Am I perto?
Solução
Você declarou o seu parâmetro a ser MetaData
em vez de MetaData[]
- em outras palavras, não é um array. Você está em seguida, usando utilArray.Name
um pouco muito, mas não está claro o porquê.
Eu suspeito que você realmente quer:
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;
}
A propósito, você pode querer considerar uma directiva using
para tornar isso mais fácil para ler:
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;
}
Outra alternativa é Array.ConvertAll
:
ProxyMetaData[] output = Array.ConvertAll(input,
metaData => new ProxyMetaData(metaData.Name, metaData.Value));
Se você não estiver usando C # 3, você pode usar um método anônimo para isso. Se ProxyMetaData
não tem um construtor apropriado e você são usando C # 3, você pode usar um objeto inicializador:
ProxyMetaData[] output = Array.ConvertAll(input,
metaData => new ProxyMetaData { metaData.Name, metaData.Value });
Se você está preso com C # 2 e nenhum construtor for o caso, então:
ProxyMetaData[] output = Array.ConvertAll(input, delegate(MetaData metaData)
{
ProxyMetaData proxy = new ProxyMetaData();
proxy.Name = metaData.Name;
proxy.Value = metaData.Value;
});
I pensar que está coberto todas as bases:)
Outras dicas
Gostaria apenas de usar LINQ para fazer isso:
TRIMBrokerASMXProxy.ASMXProxy.MetaData[] kvData =
metaDataArray.Select(d =>
new TRIMBrokerASMXProxy.ASMXProxy.MetaData(
d.Name, d.Value)).ToArray();
Além disso, se você estiver usando o .NET 3.5, isso significa que você pode usar WCF, bem como, que é o que você deve estar usando para gerar o proxy. Você seria capaz de atribuir o seu tipo TRIMBrokerASMXProxy.ASMXProxy.MetaData com o atributo DataContract e os membros sendo serializado com o atributo DataMember. Então, você seria capaz de definir o seu contrato com o tipo real, e não tem que executar a conversão em tudo.
Você também pode usar Array.ConvertAll. Eu sei que você é relativamente novo para isso então deixe-me tentar explicar. Tem 2 parâmetros genéricos. A primeira é o tipo da matriz que pretende converter (vamos chamá-lo I). Ea segunda do tipo que você deseja converter para (vamos chamá-lo O). É aceita uma matriz de tipo I e retorna uma matriz de tipo O. O segundo parâmetro é um conversor delegado. Aplicando a nomear temos sua assinatura vai como.
delegate O Converter(I input);
O corpo do delegado deve conter o código necessário para fazer a conversão. Dentro da função ConvertAll, o código itera através de cada um dos valores na matriz de entrada e passa, em seguida, para o delegado. O valor devolvido pelo delegado é então armazenada em uma matriz de saída. A matriz de saída é devolvido para o utilizador uma vez que todos os valores são convertidos.
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;
});