4

BindingSource が接続または構成されている項目の Type を取得したいと思います。BindingSource.DataSource プロパティは、オブジェクト、リスト、または型に設定できます。それが Type の場合、バインドされたアイテムがまだないことは明らかですが、それでも Type を取得したいと考えています。リストの場合、リスト タイプではなくアイテム タイプが必要です。

私は現在、IListItemType インターフェイスを実装するビジネス オブジェクトのカスタム リスト タイプを持っています。これは、しばらく前にこの問題を解決するために作成したものです。これをより一般的な方法で機能させて、どのリストでも機能するようにしたいと思います。

これを行う良い方法についてAPIドキュメントを調べましたが、これまでのところ運がありません。私は何かを見逃していますか、それともこれは私ができない、またはすべきでないことですか?

4

3 に答える 3

8

私は最近、私が探していたすべてのものを備えたフレームワークでListBindingHelperクラスに出くわしました。

System.Windows.Forms.ListBindingHelper.GetListItemType()

リストまたはコレクションに含まれる項目の型を返します。

ListBindingHelper.GetListItemProperties()

リストに含まれる項目のプロパティを記述する PropertyDescriptorCollection を返します。

于 2010-07-13T22:21:33.513 に答える
2

リストの「タイプ」を取得する完全に一般的な方法はありません。最も一般的な方法は最初の項目を調べることですが、これは誤解を招く可能性があります。特定性の低いコレクションに、より具体的なタイプのオブジェクトを含めることができるからです(つまり、コレクションは である可能性がありますが、最初の項目はである可能性があり、それが ) であると推測できます。すべての要素が同じ型であると確信している場合 (つまり、コレクションのジェネリック型または他のオブジェクトよりも具体的なものはないということです)、最初の項目を調べるのが最も簡単です。List<object>stringList<string>

それとは別に、を使用してリストの実際のタイプをGetType調べ、そのインターフェースを確認できます。厳密に型指定されコレクションは を実装IEnumerable<T>する可能性が高いため、そのインターフェイスを反復処理してIEnumerableジェネリックを探してから、そのジェネリック型引数を調べることができます。それは(以上)少しおかしなことですが、うまくいくはずです。

TL;DR バージョン

これを試して。.NET 3.5 を使用していて、リストが という変数に格納されていると仮定しますlist

var listType = list.GetType().GetInterfaces()
              .Where(t => t.Name == "IEnumerable" && t.IsGenericType)
              .Select(t => t.GetGenericArguments()[0]).FirstOrDefault();

リストが実装されている限りIEnumerable<T>、これはあなたに与えますT。そうでない場合は、リストのタイプがobjectとにかくそうである可能性があります。

于 2010-06-14T19:16:05.887 に答える
1

この回答が掲載されてからかなりの時間が経ちましたが、念のために誰かがまだ回答を探しています...

同様の問題に遭遇しました。私のシナリオでは、BindingSource.DataSource は常に IEnumerable にバインドされますが、リストに項目がない可能性があります。BindingSource には「itemType」というプライベート インスタンス メンバーがあることがわかります。BindingSource がリストにバインドされている場合はリストの要素の型を示し、リストがない場合は BindingSource がバインドされているオブジェクトの型を示します。

フィールド値にアクセスするために、ハック リフレクションを使用しました。

FieldInfo fi = 
    typeof(BindingSource)
    .GetField("itemType", BindingFlags.NonPublic | BindingFlags.Instance);
Type myElementType = fi.GetValue(DataBinder.RestrictedDataBinding) as Type;

多くの調査を行わずに、それが行っていることは、innerList の要素の型を表示していると思います。そのため、DataSource がリスト型であるかどうかは問題ではありません。また、このフィールドは、BindingSource でサポートされているあらゆる種類のリスト (IQueryables などを含む) の要素の型を正確に示すと思います。

警告: 私はこのフィールドをあまりテストしていないので、正しい要素タイプを読み取れない場合があるかどうかはわかりません。たとえば、BindingSource の DataSource プロパティがリセットされると、フィールドは常に正確に更新されますか? DataSource プロパティが別の elementType を持つリストにリセットされた場合はどうなりますか? 私の場合、これらの例外やその他の例外は適用されませんが、テストすることをお勧めします。

最後に、リフレクションを使用してプライベート フィールドをハッキングすると、あらゆる種類の oop 原則が破られます。心に留めておきます。また、itemType フィールドが非表示になっているのには十分な理由がある可能性があることに注意してください。さらに調査する必要がある場合は、BindingSource クラスのコードが公開されています。

于 2014-10-13T18:34:39.120 に答える