我有许多“section items”(Lesson,Info),它继承自常见类型SectionItem。各种类型的SectionItem共享一些但不是所有属性。
我发现将参数传递给每种对象的最佳方法是将它们全部打包在 Dictionary<string, object>
中,然后让基类SectionItem解压缩 common < / strong> ones,每个继承类解包特定的。
这个工作得很好,但这都是C#2,因为我只会在运行时捕获错误,而不是在编译期间。有没有办法用泛型更优雅地做到这一点?
alt text http://www.deviantsart.com/upload/1hqkaoc.png
using System;
using System.Collections.Generic;
using System.Text;
namespace TestPass234
{
class Program
{
static void Main(string[] args)
{
List<SectionItem> sectionItems = new List<SectionItem>();
{
Dictionary<string, object> vars = new Dictionary<string, object>();
vars.Add("sectionNumber", 1);
vars.Add("title", "Lesson #1");
vars.Add("startDate", new DateTime(2008, 12, 25));
List<Flashcard> flascards = new List<Flashcard>();
flascards.Add(new Flashcard { Question = "What color is the sky?", Answer = "blue" });
flascards.Add(new Flashcard { Question = "What color is the sun?", Answer = "yellow" });
vars.Add("flashcards", flascards);
SectionItem sectionItem = SectionItem.Instantiate("lesson", vars);
sectionItems.Add(sectionItem);
}
{
Dictionary<string, object> vars = new Dictionary<string, object>();
vars.Add("title", "Info #1");
vars.Add("content", "This is info number one.");
SectionItem sectionItem = SectionItem.Instantiate("info", vars);
sectionItems.Add(sectionItem);
}
foreach (var sectionItem in sectionItems)
{
Console.WriteLine(sectionItem.Render());
}
Console.ReadLine();
}
}
public class SectionItem
{
protected string _title;
public SectionItem()
{ }
public SectionItem(Dictionary<string, object> vars)
{
_title = Convert.ToString(vars["title"]);
}
public static SectionItem Instantiate(string idCode, Dictionary<string, object> vars)
{
switch (idCode)
{
case "lesson":
return new SectionItemLesson(vars);
case "info":
return new SectionItemInfo(vars);
default:
return new SectionItem();
}
}
public virtual string Render()
{
return "undefined section item";
}
}
public class SectionItemLesson : SectionItem
{
private int _sectionNumber;
private DateTime _startDate;
private List<Flashcard> _flashcards = new List<Flashcard>();
public SectionItemLesson(Dictionary<string, object> vars) : base(vars)
{
_sectionNumber = Convert.ToInt32(vars["sectionNumber"]);
_startDate = Convert.ToDateTime(vars["startDate"]);
_flashcards = vars["flashcards"] as List<Flashcard>;
}
public override string Render()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(">>> {0}. {1} (Starts {2:ddd, MMM d, yyyy})", _sectionNumber, _title, _startDate));
foreach (var flashcard in _flashcards)
sb.AppendLine(" - " + flashcard.Render());
return sb.ToString();
}
}
public class SectionItemInfo : SectionItem
{
private string _content;
public SectionItemInfo(Dictionary<string, object> vars)
: base(vars)
{
_content = Convert.ToString(vars["content"]);
}
public override string Render()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(">>> {0}", _title));
sb.AppendLine(String.Format(" {0}", _content));
return sb.ToString();
}
}
public class Flashcard
{
public string Question { get; set; }
public string Answer { get; set; }
public string Render()
{
return "Q: " + Question + " A: " + Answer;
}
}
}
答案 0 :(得分:2)
你能为每个SectionItem类创建一个'parameters'类吗?
public class SectionItemParameters
{
public string Title { get; set; }
}
public class SectionItemLessonParameters
: SectionItemParameters
{
public int SectionNumber { get; set; }
public DateTime StartDate { get; set; }
public List<Flashcard> Flashcards { get; set; }
}
public class SectionItemInfoParameters
: SectionItemParameters
{
public string Content { get; set; }
}
然后,层次结构中的每个类都可以在强类型对象中接收其参数。您的工厂方法Instantiate
将接受SectionItemParameters并强制转换为正在调用的构造函数的相应类型。
答案 1 :(得分:0)
如果在编译时已知可能的名称集并使用C#4,则可以在构造函数上使用default / optional参数。如果只有某些组合有效(例如,如果既没有提供“Bar”和“Baz”,则只提供“Foo”),那么你仍然需要运行时检查。
但如果名称集是真正动态的,那么只有字典或匿名类型的选项(并使用反射来提取正文中的名称集)。