Унаследованный статический член, который отличается для каждого наследуемого типа класса? - PullRequest
2 голосов
/ 14 марта 2012

Я пытаюсь создать шаблон элемента управления для таблицы, где каждый столбец связан с раскрывающимся списком возможных значений, и у каждой строки есть свой уникальный набор «выбранных значений».Это выглядит так:

<DataTemplate x:Key="ColourCellDataTemplate">
    <local:ColourDictionary Key="{TemplateBinding Content}">
        <local:ColourDictionary.ContentTemplate>
            <DataTemplate>
                <TextBlock Style="{StaticResource EditableTextCell}" Text="{Binding ColourName}" />
            </DataTemplate>
        </local:ColourDictionary.ContentTemplate>
    </local:ColourDictionary>
</DataTemplate>

У меня есть около 10 из этих классов, каждый из которых инициализируется с различным ключом данных и ключом сортировки, но все базовые операции и события одинаковы.

Каждыйиз этих классов есть свой статический кэшированный член DataView, который совместно используется всеми экземплярами этого класса:

public class ColourDictionary : DataTableDictionary
{
    private static DataView cachedView;

    public ColourDictionary(){ }

    protected override DataView createView()
    {
        if (CachedView == null)
        {
            CachedView = base.buildView(table:((App)App.Current).ApplicationData.Colours, 
                                        keyField:"ColorCode");
        }
        return CachedView;
    }
}

Как вы можете видеть - когда базовый класс переходит к созданию DataView для использования в словаре,он использует виртуальный метод, который позволяет различным наследующим классам передавать их собственное представление - но каждый класс должен отслеживать свой собственный статический кеш.

Я надеялся, что это кеширование было логикой, которую я мог сохранить вбазовый класс, так что «CreateView ()» должен будет возвращать новый DataView и вызываться только один раз, после чего базовый класс будет просто использовать свой собственный кэш для каждого наследуемого класса.


Решение

Большое спасибо за две очень хорошие и очень правильные идеи.Я надеюсь, что вы оба получите больше голосов.Я пошел с последним решением, потому что я лох для краткости.Затем я пошел немного дальше, так что реализующие классы должны только переопределить средство получения виртуального свойства для удовлетворения требований:

public class CATCodeDictionary : DataTableDictionary<CATCodeDictionary>
{
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.CATCodeList; } }
    protected override string indexKeyField { get { return "CatCode"; } }
    public CATCodeDictionary() { }
}
public class CCYDictionary : DataTableDictionary<CCYDictionary>
{
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.CCYList; } }
    protected override string indexKeyField { get { return "CCY"; } }
    public CCYDictionary() { }
}
public class COBDictionary : DataTableDictionary<COBDictionary>
{
    protected override DataTable table { get { return ((App)App.Current).ApplicationData.COBList; } }
    protected override string indexKeyField { get { return "COB"; } }
    public COBDictionary() { }
}    
etc...

Базовый класс

public abstract class DataTableDictionary<T> : where T : DataTableDictionary<T>
{
    private static DataView _IndexedView = null;

    protected abstract DataTable table { get; }
    protected abstract string indexKeyField { get; }

    public DataTableDictionary()
    {
        if( _IndexedView == null)
        {
            _IndexedView = CreateIndexedView(table.Copy(), indexKeyField);
        }
    }

    private DataView CreateIndexedView(DataTable table, string indexKey)
    {   // Create a data view sorted by ID ( keyField ) to quickly find a row.
        DataView dataView = new DataView(table);
        dataView.Sort = indexKey;
        return dataView;
    }

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

Вы можете использовать дженерики:

public class DataTableDictionary<T> where T: DataTableDictionary<T>
{
    private static DataView cachedView;  
}

public class ColourDictionary : DataTableDictionary<ColourDictionary>
{
}

public class XyDictionary : DataTableDictionary<XyDictionary>
{
}

Здесь каждый класс имеет свой статический член.

1 голос
/ 14 марта 2012

Вы можете использовать словарь для кэширования в базовом классе следующим образом:

public class DataTableDictionary
{
     private static Dictionary<Type, DataView> cachedViews = new Dictionary<Type, DataView>();

     protected abstract DataView CreateView();

     public DataView GetView()
     {
         DataView result;
         if (!cachedViews.TryGetValue(this.GetType(), out result))
         {
             result = this.CreateView();
             cachedViews[this.GetType()] = result;
         }
         return result;
     }
}

public class ColourDictionary : DataTableDictionary
{

    protected override DataView CreateView()
    {
        return base.buildView(table: ((App)App.Current).ApplicationData.Colours, keyField: "ColorCode");          
    }
}

Или вы должны использовать ConcurentDictionary, если вам нужна безопасность потоков

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...