1

1 つのクラスにジェネリック型と非ジェネリック型を含めることは可能ですか??

さまざまな型を管理する必要があるクラスがありますが、何を受け取るのか正確にはわかりません。ジェネリックの使用については考えていますが、これを行う方法が見つかりません。

これが私がやろうとしていることです

int commandCode;
<T> arg1;
<T> arg2;
<T> arg3;

テキスト ファイルから 4 行の文字列を読み取り、それらの行を解析して

  1. 整数
  2. 浮く
  3. ブール値
  4. 文字列のままにする

(最初に 1 に解析しようとします。不可能な場合は 2 に、不可能な場合は 3 に、不可能な場合は 4 に解析します。)

各引数の型がわかったら、各変数をそれぞれの型で定義します

たとえば、

  • commandCode=2
  • arg1=真
  • arg2=256
  • arg3=禁止

私はオブジェクトを持っているでしょう

  • int コマンドコード
  • < ブール値 > arg1
  • < 整数 > arg2
  • <文字列> arg3

これは、arg1 から arg3 までの可能な組み合わせで発生します。

4

2 に答える 2

1

私があなたを正しく理解していれば、実際の型は実行時にしか判断できません。その csae ジェネリックでは、コンパイル時に型引数を解決する必要があるため、何らかの方法でリフレクションを使用する必要があるため、あまり役に立ちません。以下は、ニーズをサポートするために拡張できるファクトリです。実際にサブクラスがいくつあるかに応じて、16 の異なるメソッドが必要な場合とそうでない場合があります (以下のアプローチでは、サブクラスごとに 1 つ必要です)。Create メソッドをスキップして、適切なクラス/コンストラクターを直接選択することもできます。

public class Command {

   public static Command Create(string[] textLines) {
     var args = textLines.Select(l => parseLine(l));
     var argTypes = args.Select(a => a.GetType().ToArray();
     return (Command)typeof(Command).GetMethod("Create",argTypes).Invoke(null,args);
   }

   public static Command Create(int commandType,
                                bool IsSponk,
                                int count, 
                                string description){
       return new CommandType1(commandType,
                               IsSponk,
                               count,
                               description);
   }
   private class CommandType1 : Command {
       public CommandType1(int commandType, bool IsSponk, int count, string description){
            ....
       }
   }
}
于 2013-01-09T13:03:07.297 に答える
0

読み取るデータに応じて変数の型がある場合 (あなたの場合のように)、ジェネリックを使用しても意味がありません。@Spontifixus アプローチを採用しても、作成されたすべての要素を 1 つにまとめることができません。これはList<T>、各オブジェクトで使用される異なるタイプが原因で、独自の各組み合わせに必要ですList<T>。また、後でコードですべての引数を操作したい場合は、ジェネリック型ごとにクエリを実行して、現在のインスタンスから目的の値を読み取る方法を知る必要があります。

それでもジェネリック型が必要だと思われる場合 (この場合)、ジェネリック クラス、クリエーター メソッド、および通常のインターフェイスを使用することで解決できます。

public interface ICommand
{
    int CommandCode { get; set; }
    object Argument1 { get; }
    object Argument2 { get; }
    object Argument3 { get; }
}

public static class Command
{
    public static Command<T1, T2, T3> Create<T1, T2, T3>(int code, T1 arg1, T2 arg2, T3 arg3)
    {
        return new Command<T1, T2, T3>(code, arg1, arg2, arg3);
    }
}

public class Command<T1, T2, T3> : ICommand
{
    public Command(int code, T1 arg1, T2 arg2, T3 arg3)
    {
        CommandCode = code;
        Argument1 = arg1;
        Argument2 = arg2;
        Argument3 = arg3;
    }

    public int CommandCode { get; set; }
    public T1 Argument1 { get; set; }
    public T2 Argument2 { get; set; }
    public T3 Argument3 { get; set; }

    object ICommand.Argument1
    {
        get { return Argument1; }
    }

    object ICommand.Argument2
    {
        get { return Argument2; }
    }

    object ICommand.Argument3
    {
        get { return Argument3; }
    }
}

このアプローチを使用すると、creator メソッドを呼び出すことで型推論を通じてインスタンスを作成し、それらすべてを 1 つのリストに入れることができます。

var commands = new List<ICommand>();
var myCommand = Command.Create(3, 4f, true, "hello world");
var commands.Add(myCommand);

これで汎用オブジェクトが 1 つのリストにまとめられましたが、このリストをどのように操作するのでしょうか? 最後に、常にICommandインターフェイスを使用して に固執しobject、ジェネリックを役に立たなくしています。しかし、そうは思わないかもしれません。このアプローチが役立つかもしれません。

于 2013-01-09T13:16:45.387 に答える