2010-12-28 4 views
2

Пожалуйста, позвольте мне объяснить, на мой вопрос, в этом примере:C# Как расширить класс, используемый другим классом?

Если я продлить DataTable и DataColumn:

class MyTable: DataTable 
{ 
    // Columns in here. 
} 

class MyColumn: DataColumn 
{ 
} 

Мой вопрос, как я могу позволить Колонны MyTable класса использовать расширенный MyColumn, а чем исходная DataColumn?

Спасибо.

+2

Вы можете посмотреть в использовании шаблона проектирования DAL (необязательно в сочетании с ORM), а не напрямую привязывается к конкретному представлению данных (например, DataTable). Если вы отрисуете свой уровень персистентности и сконструируете так, чтобы он был расширяемым (виртуальные методы, абстрактные методы или просто интерфейсы), тогда проблемы, подобные этому, становятся намного проще. http://en.wikipedia.org/wiki/Data_access_layer –

+0

Всецело согласен с @Merlyn Morgan-Graham. Есть лучшие способы сделать это. – Randolpho

+0

Вы имеете в виду классы ADO.NET DataTable и DataColumn? –

ответ

2

Я не совсем уверен, что вы пытаетесь выполнить, но, исходя из базовых объектов, вероятно, лучший маршрут. Дать этому спина ...

public class MyDataColumnCollection : InternalDataCollectionBase 
    { 
     private readonly ArrayList _list = new ArrayList(); 

     protected override ArrayList List 
     { 
      get 
      { 
       return this._list; 
      } 
     } 
     public void Add(MyDataColumn c) 
     { 
      this.List.Add(c); 
     } 
    } 

    public class MyDataTable : DataTable 
    { 
     private MyDataColumnCollection _columns = new MyDataColumnCollection(); 
     public new MyDataColumnCollection Columns 
     { 
      get { return this._columns; } 
     } 
    } 

    public class MyDataColumn : DataColumn 
    { 
     public string MyCustomProperty { get; set; } 
    } 

    static void Main(string[] args) 
    {   
     MyDataTable t = new MyDataTable(); 
     MyDataColumn c = new MyDataColumn(); 

     c.ColumnName = "My Test Column"; 
     c.MyCustomProperty = "This is really cool!"; 
     t.Columns.Add(c); 

     foreach (MyDataColumn mdc in t.Columns) 
     { 
      System.Diagnostics.Debug.WriteLine(mdc.MyCustomProperty); 
     }   
    } 

Источник с пользовательскими KeyedCollection <>

public class MyDataColumnCollection : 
    KeyedCollection<string, MyDataColumn> 
{ 
    protected override string GetKeyForItem(MyDataColumn item) 
    { 
     return item.ColumnName; 
    } 
} 

public class MyDataTable : DataTable 
{ 
    private MyDataColumnCollection _columns = new MyDataColumnCollection(); 
    public new MyDataColumnCollection Columns 
    { 
     get { return this._columns; } 
    } 
} 

public class MyDataColumn : DataColumn 
{ 
    public string MyCustomProperty { get; set; } 
} 

static void Main(string[] args) 
{ 

    MyDataTable t = new MyDataTable(); 
    MyDataColumn c = new MyDataColumn(); 

    c.ColumnName = "My Test Column"; 
    c.MyCustomProperty = "This is really cool!"; 
    t.Columns.Add(c); 

    foreach (MyDataColumn mdc in t.Columns) 
    { 
     System.Diagnostics.Debug.WriteLine(mdc.MyCustomProperty); 
    } 

    MyDataColumn testColumn = t.Columns["My Test Column"]; 
    System.Diagnostics.Debug.WriteLine(testColumn.MyCustomProperty); 
} 

Решение с C# Extensions:

namespace ExtensionMethods 
{ 
    public static class MyExtensions 
    { 
     public static void UpdateValue(this DataTable dt) 
     { 
      // add code to update data in the DataTable 
     } 
    } 
} 

// in another class... 
DataTable myDataTable = (Get DataTable object); 
myDataTable.UpdateValue(); 
+0

Это похоже на то, что я хочу. У меня все еще есть некоторые недоумения. В соответствии с «публичными новыми столбцами MyDataColumnCollection» исходные «Столбцы» будут заменены новым, но у него все еще будут оригинальные функции datacolumn, потому что новый расширяется от исходного datacolumn.Я прав? – Jfly

+0

Кроме того, элементы в исходных столбцах могут быть доступны с помощью ключей. Как я могу достичь этого с помощью ArrayList? – Jfly

+0

Q1: Истинное утверждение. Q2: ArrayList - это просто то, что использует исходная коллекция Columns. Вы всегда можете заменить это своей собственной коллекцией. –

2

Если ваши MyColumns получены из DataColumn, их можно поместить в DataTable как DataColumn. Затем MyTable может извлекать столбцы и добавлять их в MyColumn.

Обратите внимание, что это не самый лучший вариант; вам может быть лучше использовать что-то другое чем ADO.NET 2. Но если это маршрут, который вам нужно, это вариант для вас.

Примечание: вы должны всегда проверять тип объектов DataColumn перед повышением уровня до MyColumn, так как InvalidCastException становится проблемой для вас.

+0

После попытки использования метода @Chris Gessler. Я получил то, что хочу, но все становится слишком сложным после того, как я добавил больше вещей. Похоже, что бросок - это более простой способ. Вы упомянули, что есть другие варианты. Вы имеете в виду рамки ORM или DAL? Я попробовал немного, но они кажутся мне слишком тяжелыми. – Jfly

0

Другим решением будет использование интерфейсов.

Например, определите интерфейсы для IDataColumn и IDataTable. Тогда каждая реализация этих функций наследуется от интерфейсов.

После инициализации объекта DataTable передайте соответствующий MyColoum1, MyColoum2 и т. Д. Это очень похоже на полиморфизм, только интерфейсы позволяют вам определить абсолютный контракт без какой-либо конкретной реализации.

+1

Это будет хорошо, за исключением того, что DataTable и DataColumn являются существующими типами, которые @Jfly, по-видимому, пытается использовать, и они не используют или не определяют тезисы/контракты/интерфейсы. – Randolpho

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