2

Silverlight 用の再利用可能なライブラリを作成しています。System.Typeライブラリには内部ジェネリック型が含まれており、このジェネリック型の新しいインスタンスを作成する必要がありますが、ある時点でジェネリック型引数を使用できず、ジェネリック引数を表すオブジェクトしかありません。リフレクションを使用してインスタンスを作成しようとしましたが、このクラスは内部クラスであり、Silverlight は実質的に部分信頼で実行されるため、これは失敗します。

これが私がこれまでに試したことです:

private INonGenericInterface CreateInstance(Type type)
{
    // Activator.CreateInstance fails
    var instance = Activator.CreateInstance(
            typeof(InternalGenericType<>).MakeGenericType(type));

    // Invoking the default constructor of that type fails.
    var producer = typeof(InternalGenericType<>)
        .MakeGenericType(type)
        .GetConstructor(new Type[0])
        .Invoke(null);

    return (INonGenericInterface)producer;
}

これは私の内部タイプです。派手なものはありません:

internal class InternalGenericType<T> : INonGenericInterface
    where T : class
{
    public InternalGenericType()
    {
    }
}

Nullable<T>内部型を生成できるファクトリを作成するために、構造体をファクトリとして悪用することさえ試みました。ただし、デフォルトでNullable<T>は null 参照に変換されます。

internal static class InternalGenericTypeFactory
{
   public static INonGenericInterface Create(Type serviceType)
   {
      var nullType = typeof(Nullable<>).MakeGenericType(
         typeof(Factory<>).MakeGenericType(serviceType));

      // Activator succesfully creates the instance, but .NET
      // automatically converts default Nullable<T>s to null.
      object nullInstance = Activator.CreateInstance(nullType);

      var getValueMethod =
         nullType.GetMethod("GetValueOrDefault", new Type[0]);

      // Invoke fails, because nullInstance is a null ref.
      var factory = getValueMethod.Invoke(nullInstance, null);

      return ((IFactory)factory).CreateInstance();
   }

   internal interface IFactory
   {
      INonGenericInterface CreateInstance();
   }

   internal struct Factory<T> : IFactory where T : class
   {
       public INonGenericInterface CreateInstance()
       {
           return new InternalGenericType<T>();
       }
   }
}

ご想像のとおり、API を汚染するため、この型を公開したくありません。私は現在アイデアがありません。私のオプションは何ですか?この内部型を作成するにはどうすればよいですか?

4

2 に答える 2

4

3 番目の選択肢は、内部型をインスタンス化するメソッドを含む、ある種のファクトリ パターンをサポートすることです。また、ファクトリを公開したり、ファクトリ タイプを公開したりできます。

public class TypeFactory
{
    public static object Create<T>()
    {
         return new MyInternalType<T>();
    }
}

クラスを内部のままにして、リフレクションを介して TypeFactory のメソッドを呼び出すことができます。

public object CreateType(System.Type type)
{
    Type typeFactory = typeof(TypeFactory);
    MethodInfo m = typeFactory.GetMethod("Create").MakeGenericMethod(type);
    return m.Invoke(null, null);
}

TypeFactory は公開する必要があると思いますが、内部にすることはできません。

于 2011-03-29T18:47:28.523 に答える
3

次の 2 つの選択肢があります。

  1. タイプを公開する
  2. これを行うためにリフレクションを使用するのは避け、代わりにジェネリックを使用してください。

気に入らないという理由だけでセーフガードを回避できるのであれば、セーフガードを持つ必要はまったくありません。

于 2011-03-29T18:33:16.327 に答える