2010-08-28 2 views
4

Извините за заголовок. Я понимаю, что это не очень описательно. : |Интерфейс как возвращаемый тип свойства, когда базовый тип * может * быть другим?

Вот моя проблема. У меня есть класс 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, что доступ к определенному объекту таблицы даст мне доступ к собственности Columns из класса CompositeKey.

Как я могу это достичь? Если это невозможно, какие у меня альтернативы? Я понимаю, что могу просто добавить IList<Column> Columns в IPrimaryKey. Это, однако, не кажется правильным, если у меня есть один первичный столбец (который я знаю, что факт всегда будет один) внутри списка. Это мой первый подход к этому, поэтому я уверен, что есть возможность улучшить этот дизайн.

ответ

3

Это нормально, чтобы добавить KeyColumns к AbstractPrimaryKey, хотя PrimaryKey всегда будет иметь одно значение - по крайней мере, интерфейс будет однородным. В ADO.NET DataTable.PrimaryKey представляет собой массив из DataColumn (хотя современные ориентиры определяют, что это должен быть IList или класс коллекции).

Альтернативой было бы оставить его как есть, а затем проверить PrimaryKeyType и отличить до CompositeKey по мере необходимости. Это имело бы смысл только в том случае, если бы вам нужно было провести различие в одном месте.

1

Если абстракция IPrimaryKey, то я думаю, что наличие коллекции столбцов подходит, потому что, когда вы работаете с этой абстракцией, вы не будете знать, что есть только один столбец. Все, что вы делаете полиморфно, должно будет предположить, что PrimaryKey состоит из нуля или более столбцов (или «null или 1 или более столбцов»).

Для удобства, вы можете добавить Column собственности в PrimaryKey.

Смежные вопросы