C# 无IF条件的多态对象创建

C# 无IF条件的多态对象创建,c#,oop,C#,Oop,我有一个这样的抽象类: public abstract class Records { public string Type; public string Source; public int Value; protected Records(string type, string source, int value) { Type = type; Sourc

我有一个这样的抽象类:

public abstract class Records
    {
        public string Type;
        public string Source;
        public int Value;

        protected Records(string type, string source, int value)
        {
            Type = type;
            Source = source;
            Value = value;
        }
}
public static class ContentTypesString
    {
        public static string DocumentNew { get { return "Document - New this Month"; }}

        public static string HeadlinesNew { get { return "Headlines - New this Month"; }}

       etc...  
    }
我想创建许多继承该类的类,并用来自如下静态类的值填充其类型字段:

public abstract class Records
    {
        public string Type;
        public string Source;
        public int Value;

        protected Records(string type, string source, int value)
        {
            Type = type;
            Source = source;
            Value = value;
        }
}
public static class ContentTypesString
    {
        public static string DocumentNew { get { return "Document - New this Month"; }}

        public static string HeadlinesNew { get { return "Headlines - New this Month"; }}

       etc...  
    }
我希望能够创建这些子类,而无需测试“
如果foo==“document”,那么type=ContentTypesString.DocumentNew
”或等效的切换案例(我确实有很多案例)

有适合我需要的设计模式吗

编辑:正如一些人指出的,我应该展示如何创建实例

     private delegate SPListItemCollection Query(SPWeb web, DateTime startDate, DateTime endDate);
     private readonly Query _queries;

       #region Constructors

      public QueryHandler(SPWeb web, DateTime startTimeSelectedDate, DateTime endTimeSelectedDate)
          {
            if (web == null) throw new ArgumentNullException("web");

            _web = web;
            _startTimeSelectedDate = startTimeSelectedDate;
            _endTimeSelectedDate = endTimeSelectedDate;
            RecordsList = new List<Records>();

            // Query Invocation List
            _queries = NumberPagePerMonthQuery.PreparedQuery;
            _queries += NumberDocumentsPerMonthQuery.PreparedQuery;
            _queries += NumberHeadlinesPerMonthQuery.PreparedQuery;
            _queries += NumberLeaderboxPerMonthQuery.PreparedQuery;
            _queries += NumberNewsPerMonthQuery.PreparedQuery;
            _queries += NumberPagesModifiedPerMonthQuery.PreparedQuery;
            _queries += NumberPicturesPerMonthQuery.PreparedQuery;
            _queries += NumberTeasingPerMonthQuery.PreparedQuery;
        }

        #endregion Constructors

        #region Public Methods

        // what about NullReferenceException ? C#6 : item?.Foreach(item => {}); ?
        /*** NO C#6 compiler in VS2012... ***/
        public void Queries()
        {
            foreach (var del in _queries.GetInvocationList())
            {
                var queryresult =
                    (SPListItemCollection) del.DynamicInvoke(_web, _startTimeSelectedDate, _endTimeSelectedDate);

                RecordsList.Add(new Records(del.Method.Name, _web.Title, queryresult.Count));
            }
        }

瞧。谢谢大家的帮助。

这就是你需要的吗

public abstract class Records
{
    public string Type;
    public string Source;
    public int Value;

    protected Records(string type, string source, int value)
    {
        Type = type;
        Source = source;
        Value = value;
    }
}

public class DocumentRecords : Records
{
    public DocumentRecords(string source, int value)
        : base(ContentTypesString.DocumentNew, source, value) // use here
    {
    }
}

public class HeadlinesRecords : Records
{
    public HeadlinesRecords(string source, int value)
        : base(ContentTypesString.HeadlinesNew, source, value) // use here
    {
    }
}

public static class ContentTypesString
{
    public static string DocumentNew { get { return "Document - New this Month"; } }

    public static string HeadlinesNew { get { return "Headlines - New this Month"; } }
}

您希望通过对象类型的字符串代码和参数来收集记录

其中一种方法是使用builder

首先,我们需要配置生成器:

        var builder = new RecordBuilder()
            .RegisterBuilder("document", (source, value) => new Document(source, value))
            .RegisterBuilder("headlines", (source, value) => new Headlines(source, value));
这里我们指定如何使用代码“document”和“headlines”构建记录

要生成记录调用,请执行以下操作:

        builder.Build("document", "source", 1);
构建器代码可以通过以下方式实现 (这里我们看一下我们是否知道如何构建所传递类型的记录并使其生效):

公共类记录生成器
{
公共记录生成(字符串代码、字符串源、int值)
{
Func-buildAction;
if(recordBuilders.TryGetValue(代码,out buildAction))
{
返回buildAction(源、值);
}
返回null;
}
公共记录生成器RegisterBuilder(字符串代码,Func buildAction)
{
添加(代码,buildAction);
归还这个;
}
private Dictionary recordBuilders=新字典();
}
公共类文件:记录
{
公共文档(字符串源,int值):基(ContentTypesString.DocumentNew,源,值)
{
}
}
公开课标题:记录
{
公共标题(字符串源,int值):基(ContentTypesString.HeadlinesNew,源,值)
{
}
}

为什么不在继承的类中执行此操作<代码>公共类文档:记录{public Documents(){Type=ContentTypesString.DocumentNew;}}为什么不放一些虚拟方法getDefaultContentTypeString?是的,但是如果调用方中没有记录,我如何选择要生成的子记录?@Will:是的,构造函数名称有错误。更正。Thanks@YthioCsi打什么电话?你的问题毫无意义。这看起来很好:)但是如果调用者中没有记录,我如何选择要生成的子记录?因此,首先,你只有一个类型,你想将该类型赋予将创建相应记录的对象,然后子记录返回给你?我添加了一些关于如何创建记录实例的代码。我想去掉Method.Name,它在我看来相当脏,并在这个上下文中调用正确的记录子类构造函数。我有模糊的记忆这是可能的,但我不记得怎么做。我想我发现,我改变了我的程序很多。保存preparedQuery的静态实用程序方法成为IQuery接口的实现,委托被列表替换,委托调用列表被调用接口方法的列表上的foreach替换。接口的实现还包含一个返回所需记录子实例的方法。我不确定我是否理解您在这里做什么以及如何使用它,但它看起来更像是(非常)模糊的设计记忆,我试图在这里重现。我想我发现,我的程序改变了很多。保存preparedQuery的静态实用程序方法成为IQuery接口的实现,委托被列表替换,委托调用列表被调用接口方法的列表上的foreach替换。接口IQuery的实现还包含一个返回所需记录子实例的方法。
public class RecordBuilder
{
    public Records Build(string code, string source, int value)
    {
        Func<string, int, Records> buildAction;

        if (recordBuilders.TryGetValue(code, out buildAction))
        {
            return buildAction(source, value);
        }

        return null;
    }

    public RecordBuilder RegisterBuilder(string code, Func<string, int, Records> buildAction)
    {
        recordBuilders.Add(code, buildAction);
        return this;
    }

    private Dictionary<string, Func<string, int, Records>> recordBuilders = new Dictionary<string, Func<string, int, Records>> ();
}


public class Document : Records
{
    public Document(string source, int value) : base(ContentTypesString.DocumentNew, source, value)
    {
    }
}

public class Headlines : Records
{
    public Headlines(string source, int value) : base(ContentTypesString.HeadlinesNew, source, value)
    {
    }
}