一般的なインターフェイスを不適切に使用している可能性があると思います(しかし、よくわからないので教えてください)。競馬用の小さな継承階層があります。IMeeting + IRace + IRunner の 3 つの主要なインターフェイスがありますが、この例では縮小しました。ミーティングには、ランナーを含むレースが含まれています。具体的な型の実行時決定を行うためにジェネリックを使用しましたが、見栄えが悪く、WriteData メソッドの param は、IRace などの型を宣言する必要がある IMeeting の型を宣言する必要があります。
static void WriteData(IMeeting<IRace<IRunner, string>> meeting)
ここに小さな例があります:
class Program
{
static void Main(string[] args)
{
IMeeting<IRace<IRunner, string>> meeting = new Meeting<IRace<IRunner, string>>();
IRace<IRunner, string> slrace = new SL_Race<IRunner, string>();
IRunner slrunner = new SL_Runner();
slrace.Runners.Add(slrunner);
meeting.Races.Add(slrace);
WriteData(meeting);
}
static void WriteData(IMeeting<IRace<IRunner, string>> meeting)
{
// Write to db or whatever
}
}
public interface IMeeting<T_Race>
{
string Course { get; set; }
string CourseId { get; set; }
List<T_Race> Races { get; set; }
}
public class Meeting<T_Race> : IMeeting<T_Race>
{
public string Course { get; set; }
public string CourseId { get; set; }
public List<T_Race> Races { get; set; }
public Meeting()
{
Races = new List<T_Race>();
}
}
public interface IRace<T_Runner, T_Going>
{
T_Going Going { get; set; }
List<T_Runner> Runners { get; set; }
}
public interface ISL_Race<T_Runner, T_Going> : IRace<T_Runner, T_Going>
{
// Extended behaviour
string Time { get; set; }
string RaceId { get; set; }
string Info { get; set; }
uint MaxOR { get; set; }
}
public class SL_Race<T_Runner, T_Going> : ISL_Race<T_Runner, T_Going>
{
// IRace
public T_Going Going { get; set; }
public List<T_Runner> Runners { get; set; }
// ISL_RACE
public string Time { get; set; }
public string RaceId { get; set; }
public string Info { get; set; }
public uint MaxOR { get; set; }
public SL_Race()
{
Runners = new List<T_Runner>();
}
}
public interface IRunner
{
string Name { get; set; }
}
public class SL_Runner : IRunner
{
public string Name { get; set; }
}
私の現実世界のアプリには、いくつかの異なるタイプのコンクリート ランナーとレースがあります。実行時に関連する会議を作成しようとしています。私の考えでは、IMeetingにはIRacesの宣言が必要ですが、具体的なレースタイプは実行時まで知ることができず、ランナーについても同じです。私の現実世界のアプリには、より一般的なパラメーターもあり、階層の上位の型を認識しなければならない見苦しいメソッド署名になってしまいます。
public List<IMeeting<IRP_Race<IRP_Runner, Going>>> ExtractMeetingList(String dayResultPage)
では、ジェネリックを不適切に使用しているのでしょうか? ジェネリック プロパティを具象クラスに移動することですべてのジェネリックを削除し、それらを非ジェネリックとして指定できます。たとえば、IRace.Runners を SL_Race クラスに移動できますが、レース インターフェイスにはランナーが必要なため、IRace にある必要があるように思えます。
ご意見ありがとうございます。
**編集 - 考えてみると、おそらくジェネリックを削除して、コンパイル時に認識される必要な型を持つサブクラスを作成する必要があります。
public interface IMeeting
{
string Course { get; set; }
string CourseId { get; set; }
}
// This is the new subclass with the list of concrete races "ISL_RACE"
public class ISL_Meeting : IMeeting
{
List<ISL_Race> Races { get; set; }
}
public class SL_Meeting : ISL_Meeting
{
public string Course { get; set; }
public string CourseId { get; set; }
List<ISL_Race> Races {get; set;}
public SL_Meeting()
{
Races = new List<ISL_Race>();
}
}