【问题标题】:Inherited static member that's different for each inheriting class type?每个继承类类型都不同的继承静态成员?
【发布时间】:2012-03-30 23:32:10
【问题描述】:

我正在尝试为表格制作控制模板,其中每一列都与可能值的下拉列表相关,并且每一行都有自己独特的“选定值”集。它看起来像这样:

<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 并且只会被调用一次,之后基类将简单地使用它每个继承类类型都有自己的缓存。


解决方案

非常感谢您提出两个非常好的和非常有效的想法。希望大家多多点赞。我选择了后一种解决方案,因为为了简洁起见,我是个傻瓜。然后我更进一步,实现类只需要重写一个虚拟属性 getter 即可满足要求:

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;
    }

【问题讨论】:

    标签: c# xaml inheritance .net-4.0 static


    【解决方案1】:

    你可以使用泛型:

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

    这里每个类都有自己的静态成员。

    【讨论】:

    • 两个很好的解决方案。我喜欢它的简洁性。
    【解决方案2】:

    您可以像这样在基类中使用 Dictionary 进行缓存:

    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,如果你需要线程安全

    【讨论】:

    • 两个很好的解决方案。我喜欢它的清晰性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多