具有通用属性的泛型类?

时间:2011-03-01 17:18:07

标签: c# generics architecture

我有一个场景,我有一堆工作,我计划在不同的时间运行,工作本身一直在处理,这是伟大的。我有一个抽象的BaseJob类,它们都继承自我用于常见事物的类(如jobPK,startTime,异常日志记录,报告等)。但除此之外,作业是非常不同的,它们具有与它们相关的不同属性和数据,这些特性对于它们来说是特定的(我将这些属性称为JobDetails)。例如:

JobDetails for Job1
-customerId int
-cost double
-sku string
-userDefinedProperties SomeCustomObjectType

JobDetails for Job2
-name string
-executionDate DateTime
-otherProperties SomeOtherCustomObjectType

在基类中,我希望能够以尽可能通用的方式存储对这些JobDetails的引用(换句话说,我不想只将它存储为对象)以最小化拳击的开销/拆箱。然后我想让BaseJob类处理应用程序所需的许多常用功能,例如,如果作业失败,我想将其JobDetails保存到数据库中,以便可以重新启动它,我也想要记录可能发生在给定作业上的任何错误。为此,我需要能够提取那些JobDetails并使用它们。

似乎我需要使用.NET泛型并拥有一类通用属性,我可以填充任何东西,而不必担心打字。处理此问题并使其高效灵活的最佳方法是什么?

我希望这很清楚,谢谢你的帮助

2 个答案:

答案 0 :(得分:1)

您可以使JobDetails实现一个接口,让BaseJob具有对它的抽象引用。然后在实际的作业中,使用您想要的实现实现抽象JobDetails。然后让JobDetails接口定义需要使用的方法BaseJob。这是Template Method设计模式的略微变化。它看起来像这样:

public interface IJobDetails {
    void DoSomeWork();
}

public abstract BaseJob {

    protected abstract IJobDetails JobDetails { get; set; }

    public ExecuteJob {
        //execute the job
        JobDetails.DoSomeWork();
    }
}

public Job1 : BaseJob {

    public Job1() {
        JobDetails = new ConcreteJobDetails();
    }

    protected override IJobDetails JobDetails { get; set; }
}

答案 1 :(得分:0)

怎么样......

public abstract class JobBase<TDetails>
{
    private TDetails details;
    protected TDetails Details
    {
        get
        {
            if (details == null)
            {
                this.details = this.LoadDetails();
            }

            return this.details;
        }
    }

    protected virtual TDetails LoadDetails()
    {
        // Some kind of deserialization of TDetails from your DB storage.
    }
}

public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
    public class ExampleJobDetails
    {
        public string ExampleProperty { get; set; }
        public int AnotherProperty { get; set; }
    }
}

您要么为每个用作TDetails的类型都有表格,要么为所有这些表格提供一个基于键/值的大表格。两者都有利弊。如果你对拳击超级偏执,那么TDetails也不能被限制为一个结构。

编辑:向后看,你想保存失败的详细信息。怎么样......

public abstract class JobBase<TDetails>
{
    protected TDetails Details { get; private set; }

    public JobBase()
    {
        this.Details = this.CreateDetails();
    }

    protected abstract TDetails CreateDetails();

    protected void SaveDetails()
    {
        // Generic save to database.
    }
}

public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
    public class ExampleJobDetails
    {
        public string ExampleProperty { get; set; }
        public int AnotherProperty { get; set; }
    }

    protected override ExampleJobDetails CreateDetails()
    {
        return new ExampleJobDetails() { ExampleProperty = "Hi.", AnotherProperty = 1 };
    }
}