2

私のアプリケーションは IList を処理しています。さまざまなユーザー定義型の IList。リフレクションを使用して IList に含まれるオブジェクトのタイプを確認し、そのタイプの新しいインスタンスを作成して、それを IList 自体に追加できると考えていますか?

だからいつでも私は処理しているかもしれません

IList<Customer> l;

Customer の新しいインスタンスを作成したい

Customer c = new Customer(0, "None")

そしてそれをリストに追加します

l.Add(c);

明らかに、これを実行時に動的に行うことが問題の核心です。誰かが私にいくつかの指針を教えてくれることを願っています。ありがとうブレンダン

4

8 に答える 8

4

これを試して:

    public static void AddNewElement<T>(IList<T> l, int i, string s)
    {
        T obj = (T)Activator.CreateInstance(typeof(T), new object[] { i, s });
        l.Add(obj);
    }

使用法:

    IList<Customer> l = new List<Customer>();
    l.Add(new Customer(1,"Hi there ..."));

    AddNewElement(l, 0, "None");

(編集):

次にこれを試してください:

    public static void AddNewElement2(IList l, int i, string s)
    {
        if (l == null || l.Count == 0)
            throw new ArgumentNullException();
        object obj = Activator.CreateInstance(l[0].GetType(), new object[] { i, s });
        l.Add(obj);
    }
于 2009-02-04T13:52:38.510 に答える
2

パラメータなしのコンストラクタを使用し、後でプロパティを設定できる場合は、次のようにメソッドをジェネリックにすることができます。-

    void Process<T>(IList<T> list, int x, string y) where T : MyBase, new()
    {
        T t = new T();
        t.X = x;
        t.Y = y;
        list.Add(t);
    }

MyBaseは、intプロパティとstringプロパティを公開するクラスのベースです。必要に応じて、基本クラスではなくインターフェースを使用できます。

于 2009-02-04T13:38:10.660 に答える
1

このメソッドを使用してActivator.CreateInstance、型名(文字列として)またはのインスタンスを介してクラスのコンストラクターを呼び出すことができますSystem.Type

于 2009-02-04T13:38:10.990 に答える
1

Type.GetGenericArguments メソッドを使用して、ジェネリック型 IList<T> の型引数を返すことができます。次に、適切なコンストラクターを呼び出します。

  Type T = l.GetType ( ).GetGenericArguments ( ) [ 0 ];
  ConstructorInfo ctor = T.GetConstructor (
    new Type [ 2 ] { typeof ( int ), typeof ( string ) } );
  System.Diagnostics.Debug.Assert ( ctor != null );
  object instance = ctor.Invoke (
    new object [ 2 ] { 0, "None" } );
于 2009-02-04T17:13:50.460 に答える
1

デザインを変えたほうがいいと思います。抽象ファクトリ パターンを使用できます。リフレクションを使用すると、パフォーマンスが低下します。

これが工場のコードです。

public abstract class MyStore {
    public abstract string Name { get; }
    public abstract void AddItem(int id, string name);
}

抽象クラスにコードがない場合は、インターフェイスの使用を検討できます。

次に、顧客ストアを作成します。

public class CustomerStore : MyStore, IEnumerable<Customer> {
    List<Customer> list = new List<Customer>();

    public override string Name { get { return "Customer Store"; } }
    public override void AddItem(int id, string name) {
        list.Add(new Customer(id, name));
    }
    public IEnumerator<Customer> GetEnumerator() {
        return list.GetEnumerator();
    }
}

使用法

foreach (MyStore store in List<MyStore>)
    store.AddItem(0, "None");

店舗のタイプを検討したい場合は、

switch (store.Name) {
case "Customer Store":
    SomeMethod((CustomerStore)store);
    break;
default:
    throw new WhatEverException();
}
于 2009-02-04T15:35:28.193 に答える
0

The best way to get the type of the IList is to look at the property type of the indexer!

var collectionType = targetList.GetType().GetProperty("Item").PropertyType;
var constructor = collectionType.GetConstructor(Type.EmptyTypes);
var newInstance = constructor.Invoke(null);
于 2010-12-27T06:34:48.600 に答える
0

ここでの大きな問題は、タイプがわからない場合、新しいタイプを作成する方法をどのように知ることができるかということです。世界中のすべての型に、int と文字列を取るコンストラクタがあるわけではありません。

于 2009-02-04T13:31:52.657 に答える