2016-11-04 83 views
0

我有一个抽象类,它带有一个int List字段和我想要控制的属性,因为它总是需要排序。停止使用抽象类的List类中的Add和Remove方法

public abstract partial class FindAndReplace : Form { 

    private readonly List<int> _columnsToSearch = new List<int>(); 
    public List<int> ColumnsToSearch { get { return _columnsToSearch; } } 

    public void AddToColumnsToSearch(int intToAdd) { 
     _columnsToSearch.Add(intToAdd); 
     _columnsToSearch.Sort(); 
    } 

    protected abstract void ColumnCheckBox_CheckChanged(object sender, EventArgs e); 

    ... 
} 

这是FindAndReplace的子类。我想强制它使用FindAndReplace的方法AddToColumnsToSearch,但在子类中,ColumnsToSearch上的Add方法仍然可用。我的印象是,使_columnsToSearch只读,只给ColumnsToSearch上的get方法会隐藏任何方法,如ColumnsToSearch上的添加和删除。

public partial class StepsTableFindAndReplace : FindAndReplace { 

    protected override void ColumnCheckBox_CheckChanged(object sender, EventArgs e) { 
     CheckBox cb = sender as CheckBox; 

     //get the columnIndex (removed the actual "get" code to keep simpler) 
     int colIndex = 0; 

     //can still use Add and Remove, want it to be 
     //AddToColumnsToSearch(colIndex) and RemoveFromColumnsToSearch(colIndex) 
     if (cb.Checked) ColumnsToSearch.Add(colIndex); 
     else   ColumnsToSearch.Remove(colIndex); 
    } 

    ... 
} 

有什么我做错了/不理解?

对于这个问题的答案给了我这个解决方案(即不工作)... C# get and set properties for a List Collection

+0

你可以建立你自己的实现IList <>的类,并在调用Add方法时实现你的需求 –

回答

0

尽量暴露ReadOnlyCollection<T>代替List<T>

0

readonly修饰符不会使集合成为只读;它只是防止在构造函数外设置字段。公共财产应该公开为IReadOnlyCollection<int>,后台字段应为protected以允许子类修改列表。

1

readonly修饰符只能防止重新分配,并且使用ReadOnlyCollection<T>不能做你想要的,因为你想在运行时改变它。

可以代替改变的private List<int>protected SortedSet<int>,这种种本身在修改:

public abstract partial class FindAndReplace : Form 
{ 
    protected readonly SortedSet<int> _columnsToSearch = new SortedSet<int>(); 

    // ... 

然后你就可以直接派生类访问:

if (cb.Checked) 
{ 
    _columnsToSearch.Add(colIndex); 
} 
else 
{ 
    _columnsToSearch.Remove(colIndex); 
} 

然后返回新的收集访问时,例如通过ToArray()

public IEnumerable<int> ColumnsToSearch 
{ 
    get 
    { 
     return _columnsToSearch.ToArray(); 
    } 
} 

注意,后者创建了一个断开的情况:访问ColumnsToSearch给你的_columnsToSearch副本在那一刻,违背了一个ReadOnlyCollection,这是在List<T>的包装。

+0

是否有更好的方式保持列表排序而不是强制自定义添加和删除方法? –

+0

这种方法保持列表排序,不需要自定义添加和删除方法,所以我不明白你的问题。 – CodeCaster

+0

CheckChanged事件处理程序位于子类中,因此_columnsToSearch将无法进行添加或删除操作。此事件处理程序必须位于子类版本中,因为获取列索引的方法不可能为抽象类执行。 –