2

抽象型から継承する具象インスタンスを返すファクトリクラスがあります。これらの具象インスタンスには、各インスタンスが異なるデータ型を必要とするため、データ型の汎用プロパティもあります。Dataプロパティは、ファクトリで設定されているため、抽象型にも存在します。

public static class FactoryClass 
{
  public static TType CreateNewClass<TType>(object data) 
        where TType : AbstractClass<object>, new()
  {
    var newClass = new TType {Data = data};
    // do some stuff
    // keep track of all created types in a list
    List.Add(newClass);
    return newClass;
  }

  private List<AbstractClass<object>> MyList = new List<AbstractClass<object>>()
}

public abstract class AbstractClass<TData>
{
  internal AbstractClass()
  {
    // do constructor things
  }

  protected SomeCommonFunction()
  {
    // common code for abstract base class
  }

  public abstract void DoSomethingToData();

  TData Data;
}

public class ExampleClass : AbstractClass<string[]>
{
  public override void DoSomethingToData()
  {
    // sort the strings or something
    // call the abstract code
  }
}

電話をかけようとFactoryClass.CreateNewClass<ExampleClass>(myStringArray)すると、キャスト可能である必要があるというエラーが表示されます。AbstractClass<object>

私がやろうとしていることをするためのより良い方法はありますか?

4

1 に答える 1

3

これが問題です。

where TType : AbstractClass<object>

その制約は、まさにコンパイラが不平を言っているものです。

あなたが本当にこのようなものを望んでいるように私には聞こえます:

public static TContainer CreateNewClass<TContainer, TData>(TData data) 
    where TContainer : AbstractClass<TData>, new()

残念ながら、その場合は、メソッドに両方の型引数を指定する必要がありますが、少なくとも、使用しているデータの型に関しては安全です。2つのジェネリックメソッドと、それらの間で使用される個別のクラスを作成することで、これを回避できる場合があります。これにより、次のような記述が可能になります。

FactoryClass.For(myStringArray).CreateNewClass<ExampleClass>();

このForメソッドは、型引数が。のジェネリック型を返し、データ型のコンテナー型を取得するインスタンスメソッドになりますstring[]CreateNewClass

ただし、リストは現在の形式では機能しません。次の非ジェネリック基本クラスを作成することをお勧めしますAbstractClass

public abstract class AbstractClass
{
    // Anything which doesn't use TData
}

それから:

public abstract class AbstractClass<TData> : AbstractClass

その時点で、ファクトリのリストはList<AbstractClass>;になります。コンパイル時に安全な方法で各エントリのデータ型を知ることはできません...各要素が異なる型を使用する可能性があるため、これは完全に理にかなっています。

(ああ、もちろん、静的メソッドからアクセスする場合は、リストフィールドを静的にする必要があります...)

于 2013-01-31T17:13:21.177 に答える