2

前回の質問では、すべての派生クラスに独自のオプション クラスを実装させたいと考えていました。与えられた答えは私の問題の解決策を提供しましたが、オブジェクトハンドルをアンラップできなくなったため、別の問題が発生しました。

空のパブリック インターフェイスとそれを実装するクラスを作成しました。

public interface IOptions{};

public class SearchOptions : IOptions
{
    public Boolean SearchHiddenFiles { get; set; }
    public Boolean CaseSensitive { get; set; }
}

TaskOptions次に、IOptions の型である抽象パラメーターを持つ基本クラスを作成しました。

public abstract class Task<T> where T : IOptions
{
  public string ID {get; set;}
  public string Name {get; set;}

  public abstract T TaskOptions { get; set; }
  public abstract void Execute();
}

最後に、Task クラスを拡張する一連のクラスを作成しました。

public class TaskSearch : Task <SearchOptions>
{
    public override SearchOptions TaskOptions { get; set; }
    public override void Execute()
    {
        Console.Write("Search running");
    }
}

メイン プログラムは、ID、名前などを定義する json 表記を持つファイルをタスクと共に取得する Job オブジェクトを初期化します。

最後に、ジョブクラスは次のとおりです。

public class Job
{
    public String Name { get; set; }
    public String Description { get; set; }
    public List<Task<IParameters>> Tasks { get; set; }
    public Job(string JsonFile)
    {        
        using (StreamReader file = File.OpenText(JsonFile))
        {
            string json = file.ReadToEnd();
            JObject o = JObject.Parse(json);

            this.Name = o.SelectToken("Name").ToString();
            this.Description = o.SelectToken("Description").ToString();

            JArray arr = (JArray)o["Tasks"];

            foreach (var t in arr)
            {
                var taskclass = t["Name"].ToString();

                var taskobj = Activator.CreateInstance("RunTasks", "RunTasks." + taskclass);

                var task = (Task<IParameters>)taskobj.Unwrap(); //<-- throws System.InvalidCastException because taskobj is TaskSearch
                // set task.ID, task.Name, etc..
                //...
                //...
                Tasks.Add(task);
            }
        }
    }
}

Task クラスを変更して IOptions インターフェイスを実装する前に、次のようにアンラップしました。

var task = (Task)taskobj.Unwrap();

これは機能しましたが、追加IOptionsしてキャストした後Task<IOptions>、taskobj は TaskSearch (Task ではない) であるため、System.InvalidCastException エラーがスローされます。

手動で入力Task<SearchOptions>するとラップが解除れますが、タイプがTask<IOptions>. Tasksリストをジェネリックにして、すべての派生クラスを受け入れ、taskobj をアンラップする前に型パラメーターを取得する方法を見つけるか、現在のタスク名を保持するtaskclass文字列から取得する方法を見つける必要があります。

必要に応じてオプションの辞書を作成しますが、これが私が実装したかった方法であり、できるかどうか知りたいです。

ありがとうございました

4

1 に答える 1