Como desserializar Ienumerable.ToList <> () para List <>
-
05-07-2019 - |
Pergunta
Eu estou tentando construir um objeto que é algo como isto:
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return items.AsEnumerable().ToList<AnotherObject>();
}
}
Eu estou usando NHibernate como meu DAL e tê-lo mapeando diretamente para o campo de itens e tudo o que funciona bem.
Eu também estou usando Windows Workflow ea atividade replicador não funciona com o IList genérico. ( http: // sociais .msdn.microsoft.com / Fóruns / en-US / windowsworkflowfoundation / thread / 2ca74b60-fd33-4031-be4b-17a79e9afe63 ) Esta é, basicamente, me forçando a usar o List <> embalagem em vez do IList <>. Este de quebras curso o mapeamento NHibernate direta como a implementação IList do NHibernate não pode ser convertido diretamente para uma lista.
** EDIT:. A exigência Windows Workflow realmente significa que eu vou acesso de tipo seguro perder para a lista de não importa o que uma vez que requer um IList
Agora, o objetivo é serialize / desserializar este objeto. Esta multa trabalha com serialização binária, mas subjacentes aos objetos proxy do NHibernate explodir com erros nhibernate ao tentar desserializar-los.
Então, eu tentei xml serialização. A serialização funciona bem e me dá minhas definições agradáveis ??classe concreta no arquivo XML serializado que retira os proxies nhibernate completamente. No entanto, ao tentar desserializar isso, eu sou incapaz de adicionar os itens para a lista como a chamada items.AsEnumerable.ToList não vai deixar itens são adicionados à lista subjacente através do método .Add.
Alguém tem alguma opinião sobre isso? Eu vou sobre este o caminho errado?
EDIT **: A classe concreta NHibernate é NHibernate.Collection.Generic.PersistentGenericBag que, de fato, implementar IList diretamente. No entanto, eu perdi todos os benefícios de tipo seguro da lista genérica. Isso me coloca de volta no reino de ter que escrever um wrapper para cada objeto filho e eu realmente queria evitar que se possível.
Solução
Na opção é criar sua própria implementação CustomList que é invólucro em torno de uma instância que implementa IList
ou seja:
public CustomList<AnotherObject> Items
{
return new CustomList<AnotherObject>(items);
}
i. quando você adicionar à sua CustomList<T>
ele adiciona à lista de apoio.
Parece que desde que seus implementos classe IList
, bem como IList<T>
você vai ficar bem.
Outras dicas
Sim, infelizmente, você não pode fazê-lo desta forma. Chamando ToList()
cria uma nova instância da lista, então quando você adicionar itens a essa instância eles não vão reflectir-se na lista original (como você claramente descoberto).
Não uso NHibernate, mas eu seria curioso para ver se seus implementos recipiente IList
(a versão não-genérico). A partir do fio você referenciou, parece que System.Collections.IList
é o que é realmente necessário (e que é implementado por List<T>
, razão pela qual ele funciona). Será que o seu recipiente implementar IList
?
Você não pode simplesmente lançá-lo assim?
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items()
{
return (List<AnotherObject>)items;
}
}
não tive a chance de experimentá-lo, mas eu acho que deve funcionar!
Eu acho que os instrumentos de coleta de NHibernate PersistentBag (não-genérico) IList
assim você pode digitar itens como IList
vez de IList<AnotherObject>
. O link na sua pergunta afirma que o problema é que replicador requer um IList que implementa List<T>
mas IList<T>
não (vai a figura).
É possível que ser convertido para IEnumerable
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return new List<AnotherObject>items.Cast<AnotherObject>());
}
// or, to prevent modifying the list
public IEnumerable<AnotherObject> Items
{
return items.Cast<AnotherObject>();
}
}