Ienumerable.ToList<>()をリスト<>にデシリアライズする方法
-
05-07-2019 - |
質問
次のようなオブジェクトを作成しようとしています:
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items
{
return items.AsEnumerable().ToList<AnotherObject>();
}
}
NHibernateをDALとして使用し、itemsフィールドに直接マッピングし、すべて正常に機能するようにします。
また、Windowsワークフローを使用していますが、レプリケーターアクティビティが汎用IListで機能しません。 ( http:// social .msdn.microsoft.com / Forums / en-US / windowsworkflowfoundation / thread / 2ca74b60-fd33-4031-be4b-17a79e9afe63 )これは基本的にリストの使用を強制しています&lt;&gt; IList&lt;&gt;の代わりのラッパー。もちろん、NHibernateのIList実装は直接Listにキャストできないため、NHibernateの直接マッピングは中断されます。
**編集:Windowsワークフローの要件は、実際には、IListが必要なため、リストへのタイプセーフなアクセスが失われることを意味します。
現在の目標は、このオブジェクトをシリアル化/逆シリアル化することです。これはバイナリシリアル化では問題なく動作しますが、基になるNHibernateプロキシオブジェクトは、逆シリアル化しようとするとnhibernateエラーで爆発します。
だから、xmlシリアル化を試しました。シリアル化は正常に機能し、nhibernateプロキシを完全に削除するシリアル化されたxmlファイル内の私の素敵な具体的なクラス定義を提供します。ただし、これを逆シリアル化しようとすると、items.AsEnumerable.ToList呼び出しでは.Addメソッドを介して基になるリストにアイテムを追加できないため、リストにアイテムを追加できません。
これについて何か考えはありますか?私はこれについて間違った方法で行っていますか?
**編集:NHibernateの具象クラスはNHibernate.Collection.Generic.PersistentGenericBagで、実際にIListを直接実装します。ただし、ジェネリックリストのタイプセーフな利点はすべて失いました。これにより、子オブジェクトごとにラッパーを作成する必要が生じたため、可能であればそれを回避したかったのです。
解決
オンオプションは、IListを実装するインスタンスのラッパーである独自のCustomList実装を作成することです
i.e:
public CustomList<AnotherObject> Items
{
return new CustomList<AnotherObject>(items);
}
i.e。 CustomList&lt; T&gt;
に追加すると、バッキングリストに追加されます。
クラスが IList
および IList&lt; T&gt;
を実装している限り、問題はないようです。
他のヒント
はい、残念ながらこの方法で対処することはできません。 ToList()
を呼び出すと、リストのまったく新しいインスタンスが作成されるため、そのインスタンスにアイテムを追加しても、元のリストには反映されません(明らかにわかっているように)。
NHibernateを使用していませんが、コンテナが IList
(非ジェネリック版)を実装しているかどうかを知りたいです。参照したスレッドから、 System.Collections.IList
が実際に必要なものであるように見えます(そして、それは List&lt; T&gt;
によって実装されているため、動作します)。コンテナは IList
を実装していますか?
このようにキャストすることはできませんか?
public class MyObject
{
private IList<AnotherObject> items;
public List<AnotherObject> Items()
{
return (List<AnotherObject>)items;
}
}
試してみる機会はありませんでしたが、うまくいくと思います!
NHibernate PersistentBag(非ジェネリック)コレクションは IList
を実装しているため、 IList&lt; AnotherObject&gt;
ではなく IList
としてアイテムを入力できます。 。あなたの質問のリンクは、問題はレプリケーターが List&lt; T&gt;
を実装するIListを必要とするが、 IList&lt; T&gt;
は必要ではないということです(図を参照)。 >
IEnumerable&lt; T&gt;にキャストできますか?これを試すことができます:
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>();
}
}