基本アクティビティクラスを作成し、そこから他のオブジェクトを継承することができます。基本クラスには、アクティビティーのタイプを追跡するために使用できるアクティビティー・タイプがあります。
は、列挙型としてこれを定義します。
public enum ActivityType
{
Book,
Journal,
Grant
}
あなたのベースクラスは、共通のプロパティを保持します。また、アクティビティタイプと配列から派生クラスを作成するコンストラクタも用意されています。配列ベースのコンストラクタを使用するので、配列の長さを検証し、配列オブジェクトを正しい型に変換するために使用できる保護されたメンバーを追加します。
public abstract class Activity
{
public int Id { get; set; }
public int PersonId { get; set; }
public ActivityType ActivityType { get; private set; } // consider to use enum
public Activity(ActivityType activityType)
{
ActivityType = activityType;
}
public Activity(object[] values)
{
if (values.Length < 4)
throw new ArgumentException();
this.Id = getInt(values[0]);
this.PersonId = getInt(values[1]);
this.ActivityType = getActivityType(values[2]);
}
protected int getInt(object value)
{
if (!(value is int))
{
throw new ArgumentException();
}
return (int)value;
}
protected string getString(object value)
{
if (!(value is string))
{
throw new ArgumentException();
}
return (string)value;
}
protected decimal getDecimal(object value)
{
if (!(value is decimal))
{
throw new ArgumentException();
}
return (decimal)value;
}
protected ActivityType getActivityType(object value)
{
ActivityType result;
if(value is string)
{
if (!Enum.TryParse((string)value, out result))
{
throw new ArgumentException();
}
}
else if(value is ActivityType)
{
result = (ActivityType)value;
}
else
{
throw new ArgumentException();
}
return result;
}
}
現在、必要に応じて基本プロパティを設定する基本コンストラクタを呼び出す派生クラスを定義します。配列のコンストラクタでは、配列の長さを検証し、配列のオブジェクトを正しい型に変換するために基本メソッドを使用します。
public class Book : Activity
{
public Book() : base(ActivityType.Book) { }
public Book(object[] values) : base(values)
{
if (values.Length != 4) throw new ArgumentException();
this.ISBN = getString(values[3]);
}
public string ISBN { get; set; }
}
public class Journal : Activity
{
public Journal() : base(ActivityType.Journal) { }
public Journal(object[] values) : base(values)
{
if (values.Length != 5) throw new ArgumentException();
this.Volume = getInt(values[3]);
this.Issue = getInt(values[4]);
}
public int Volume { get; set; }
public int Issue { get; set; }
}
public class Grant : Activity
{
public Grant() : base(ActivityType.Grant) { }
public Grant(object[] values) : base(values)
{
if (values.Length != 4) throw new ArgumentException();
this.Volume = getDecimal(values[3]);
}
public decimal Volume { get; set; }
}
最後に、ファクトリパターンを使用して、配列の配列またはアクティビティのリストからアクティビティを作成するクラスを作成します。ファクトリには、上で定義したデータをテストするメソッドもあります。
public class ActivityFactory
{
public static List<Activity> GetActivities(object[][] values)
{
List<Activity> result = new List<Activity>();
for (int i = 0; i < values.Length; i++)
{
result.Add(MakeActivity(values[i]));
}
return result;
}
static Activity MakeActivity(object[] values)
{
Activity result = null;
switch (values[2].ToString())
{
case "Book":
result = new Book(values);
break;
case "Journal":
result = new Journal(values);
break;
case "Grant":
result = new Grant(values);
break;
default:
throw new ArgumentException("Invalid activity " + values[2].ToString());
}
return result;
}
public static void RunTest()
{
object[][] values = new object[][] {
new object[] { 2, 5, "Book", "13239382"},
new object[] { 3, 5, "Journal", 5, 124},
new object[] { 4, 5, "Journal", 8, 201},
new object[] { 5, 5, "Journal", 8, 202},
new object[] { 6, 5, "Grant", 444.00m}
};
List<Activity> activities = GetActivities(values);
}
}
ありがとう!それは私が必要なもののように見えます。ここでは、それらをループし、そのタイプに基づいてプロパティを割り当てています。 ActivityTypeあたりのカスタム値を前もって用意していないので、コードの一部に乗ることさえできるかもしれないと思います。 https://dotnetfiddle.net/dXmwwK – Andy
ようこそ。あなたの問題は、.netの一般的な使用例であり、Factory Patternは、ロジックをクリーンに保ちながら、そのようなユースケースを処理する良い方法です。あなたはそれがあなたを助けたことを知っているので、回答を受け入れたものとしてマークすることができます。 –