我有许多“节项”(教训,信息),它们是从通用类型SectionItem继承的。各种类型的SectionItems共享一些但不是全部属性。

我发现将参数传递给每种对象的最佳方法是将所有参数打包在Dictionary<string, object>中,然后让基类SectionItem解压缩常见的参数,而每个继承类都解压缩特定的参数。

这已经足够好了,但是全部都是C#2,因为我只会在运行时而不是编译期间捕获错误。有没有办法用仿制药更优雅地做到这一点?

c# - Dictionary &lt;string,object&gt;是将变量的未知集合传递给构造函数的最佳方法吗?-LMLPHP
(来源:deviantsart.com

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;
        }
    }
}

最佳答案

您可以为每个SectionItem类创建一个“参数”类吗?

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并转换为要调用的构造函数的适当类型。

10-06 06:07