是否应该使用自引用通用继承,如Customer:Entity <customer> </customer>

时间:2009-07-24 05:07:44

标签: c# nhibernate generics inheritance

建议使用自引用泛型继承吗?

public abstract class Entity<T> {
    public Guid Id {get; set;}
    public int Version {get; set;}

    public T Clone() {
        ...
        // clone routine
        ...
        return T;
    }
}

public class Customer : Entity<Customer> {
    public string CustomerName {get; set;}
    ...
}

如何将Customer转换为基本实体类? “客户:实体”提供了哪些优势?我在示例中看到了这种继承,显示了NHibernate域建模。

在没有泛型的情况下使用“客户:实体”会更好吗?

2 个答案:

答案 0 :(得分:5)

你应该在需要时使用它,而不仅仅是因为你可以。在上面的示例中,实现Clone()是有意义的。但是,正如您正确指出的那样,这意味着您的实体类实际上不会具有公共基类,并且无法访问它们真正共有的属性。处理此问题的正确方法是将其拆分为通用和非通用部分:

public abstract class Entity {
    public Guid Id {get; set;}
    public int Version {get; set;}
}

public abstract class Entity<T> : Entity where T : Entity<T> {
    public T Clone() {
        ...
        // clone routine
        ...
        return T;
    }
}

另外,请注意我在where声明中添加的Entity<T>部分 - 它确保此类只能用作此递归模式的一部分。

答案 1 :(得分:3)

在我工作的公司,我工作的项目大量使用这种技巧。事实上,它甚至被提升为代码中的模式。因此,我可以从经验中说出来:不要使用它。

它们可能是自引用实现更简单,更高效和更容易阅读的情况,但我从未遇到过这种情况。大量使用它会使代码维护成为一场噩梦,并且在大多数情况下只需要正常的继承并在需要时转换方法结果就可以避免。与代码的维护成本相比,铸造到派生类的性能成本可以忽略不计。

因此,如果您找到了建议使用自引用通用继承的罕见示例,请继续执行此操作。但请事先三思,因为可能有更好的方法。