当底层类型*可能*不同时,接口作为属性返回类型?

时间:2010-08-28 01:25:31

标签: c# interface entity

对标题感到抱歉。我确实意识到这不是很具描述性。 :|

这是我的问题。我有一个Table类,它定义了为数据库表找到的各种属性。在这个对象中,我还有一个名为PrimaryKey的属性。 PrimaryKey可以是PrimaryKey类型(我知道,令人困惑)或CompositeKey。显然,单列主键由一列组成,而复合键由两列或更多列组成。

/// <summary>
/// Defines what primary keys are supported.
/// </summary>
public enum PrimaryKeyType
{
    /// <summary>
    /// Primary key consisting of one column.
    /// </summary>
    PrimaryKey,
    /// <summary>
    /// Primary key consisting of two or more columns.
    /// </summary>
    CompositeKey,
    /// <summary>
    /// Default primary key type.
    /// </summary>
    Default = PrimaryKey
}

/// <summary>
/// Defines a database table entity.
/// </summary>
public class Table
{
    public Table()
    {
        Columns = new List<Column>();
    }

    public string Name { get; set; }
    public string Owner { get; set; }
    public AbstractPrimaryKey (What must the type be) PrimaryKey { get; set; }
    public IList<Column> Columns { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

/// <summary>
/// Defines a database column entity;
/// </summary>
public class Column
{
    public string Name { get; set; }
    public bool IsPrimaryKey { get; set; }
    public string DataType { get; set; }
    public bool IsNullable { get; set; }
}

public interface IPrimaryKey
{
    PrimaryKeyType KeyType { get; }
}

public interface IPk : IPrimaryKey
{
    Column KeyColumn { get; set; }
}

public interface ICompositeKey : IPrimaryKey
{
    IList<Column> KeyColumns { get; set; }
}

public abstract class AbstractPrimaryKey
{
    public abstract PrimaryKeyType KeyType { get; }
}

/// <summary>
/// Defines a primary key entity.
/// </summary>
public class PrimaryKey : AbstractPrimaryKey, IPk
{
    public override PrimaryKeyType KeyType
    {
        get { return PrimaryKeyType.PrimaryKey; }
    }

    public Column KeyColumn { get; set; }
}

/// <summary>
/// Defines a composite key entity.
/// </summary>
public class CompositeKey : AbstractPrimaryKey, ICompositeKey
{
    public CompositeKey()
    {
        KeyColumns = new List<Column>();
    }

    public override PrimaryKeyType KeyType
    {
        get { return PrimaryKeyType.CompositeKey; }
    }

    public IList<Column> KeyColumns { get; set; }
}

我试图使其无论PrimaryKeyType如何,访问特定的Table对象将允许我从类Columns访问属性CompositeKey

我怎样才能做到这一点?如果这是不可能的,我有什么替代方案?我明白我可以简单地将IList<Column> Columns添加到IPrimaryKey。然而,如果我在列表中有一个主列(我知道事实总是一个),那么这似乎不太正确。这是我的第一次尝试,所以我确信这个设计还有改进的余地。

2 个答案:

答案 0 :(得分:3)

可以将KeyColumns属性添加到AbstractPrimaryKey,即使PrimaryKey总是有一个值 - 至少接口是统一的。在ADO.NET中,DataTable.PrimaryKey是一个DataColumn的数组(尽管现代指南要求它应该是IList或集合类)。

替代方法是保持原样,然后根据需要检查PrimaryKeyType并转换为CompositeKey。只有你只需要在一个地方做出区分,这才有意义。

答案 1 :(得分:1)

如果抽象是IPrimaryKey,那么我认为拥有一组列是合适的,因为当你使用该抽象时,你不会知道只有一列。您以多态方式执行的任何操作都必须假定PrimaryKey由零个或多个列组成(或“null或1个或更多列”)。

为方便起见,您可以将Column属性添加到PrimaryKey