Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否执行List.AddRange调用List.Add?_C#_.net_List - Fatal编程技术网

C# 是否执行List.AddRange调用List.Add?

C# 是否执行List.AddRange调用List.Add?,c#,.net,list,C#,.net,List,我有一个从List派生的自定义类,该类带有一个Add方法,该方法仅在满足某个条件时添加 我是否还需要重写*AddRange,或者AddRange只是在给定范围的每个元素上调用Add *:是,new在C#的上下文中隐藏而不是重写。如果要创建自定义集合。不要从List派生它,而是从IList或ICollection派生或直接实现它。实际上,列表类中的Add方法不是虚拟的 注意:List.AddRange使用Array.Copy 更新 继承集合时,只需重写2个方法 public class MyCol

我有一个从List派生的自定义类,该类带有一个Add方法,该方法仅在满足某个条件时添加

我是否还需要重写*AddRange,或者AddRange只是在给定范围的每个元素上调用Add


*:是,
new
在C#的上下文中隐藏而不是重写。

如果要创建自定义集合。不要从
List
派生它,而是从
IList
ICollection
派生或直接实现它。实际上,
列表
类中的
Add
方法不是虚拟的

注意:
List.AddRange
使用
Array.Copy

更新 继承集合时,只需重写2个方法

public class MyCollection : Collection<string>
{
    private bool IsValidItem(string item)
    {
        return; // Your condition : true if valid; false, otherwise.
    }

    // This method will be called when you call MyCollection.Add or MyCollection.Insert
    protected override void InsertItem(int index, string item)
    {
        if(IsValidItem(item))
            base.InsertItem(index, item);
    }

    // This method will be called when you call MyCollection[index] = newItem
    protected override void SetItem(int index, string item)
    {
        if(IsValidItem(item))
            base.SetItem(index, item);
    }
}
公共类MyCollection:集合
{
私有布尔IsValidItem(字符串项)
{
return;//您的条件:如果有效,则为true;否则为false。
}
//调用MyCollection.Add或MyCollection.Insert时将调用此方法
受保护的重写void插入项(int索引,字符串项)
{
if(IsValidItem(项目))
基本插入项(索引,项目);
}
//调用MyCollection[index]=newItem时将调用此方法
受保护的覆盖void SetItem(整数索引,字符串项)
{
if(IsValidItem(项目))
base.SetItem(索引,项);
}
}

如果要验证的项目不是
string
请将上述代码中的
string
替换为正确的类型。

如果您需要一个行为与
列表
完全相同的集合,除了只添加有效对象之外,我不会创建自定义集合

改为使用扩展名,并将它们称为
AddIfValid(T值)
AddRangeIfValid(IEnumerable)
或任何您喜欢的,只要清楚扩展名在做什么

下面是一个例子:

public static void AddIfValid(this List<T> list, T value)
{
    if (/* check if value is valid here */)
        list.Add(value);
}

不要使用改变方法语义的隐藏。这真是糟糕的设计

创建一个实现IList的新类。最简单的方法是从
集合继承
Collection
实现了
IList
,并以
受保护的虚拟
方法的形式具有四个扩展点:

InsertItem
SetItem
RemoveItem
ClearItems
因为您只需要验证添加的项目,而不需要验证删除的项目,所以只需要覆盖
InsertItem
SetItem

class MyCollection:Collection<T>
{
    private void ValidateItem(T item)
    {
       if(item is invalid)
         throw new ArgumentException("Item is invalid");
    }

    protected override InsertItem(int index, T item)
    {
        ValidateItem(item);
        base.InsertItem(index, item);
    }

    protected override SetItem(int index, T item)
    {
        ValidateItem(item);
        base.SetItem(index, item);
    }
}
class MyCollection:集合
{
私有无效验证项(T项)
{
如果(项目无效)
抛出新ArgumentException(“项无效”);
}
受保护的重写插入项(int索引,T项)
{
验证项(项目);
基本插入项(索引,项目);
}
受保护的覆盖SetItem(int索引,T项)
{
验证项(项目);
base.SetItem(索引,项);
}
}

列表上的
.Add
方法不是虚拟的,所以我想知道你是如何覆盖它的。@DarinDimitrov使用
new
@Superbest“它实际上可以工作”算是一种好处吗?
AddRange
调用
Add
与否无关。它当然不会调用隐藏的
Add
,而是调用隐藏的
Add
。不,它不起作用。这是一个巨大的LSP违规。如何从
集合
派生出“更多的工作”?@Superbest派生自
集合
是实现
IList
的一个特例,旨在简化您的特定问题。为什么它与
List.AddRange()相关
实际实现?@svick List不能派生,因为它的方法不是虚拟的,与集合相反。List.AddRange是使用Array.Copy.Yes实现的,我理解。这就是为什么我问你为什么提到
List.AddRange()
。它不会以这种或那种方式影响结果(正是因为
List.Add()
不是虚拟的)。
Collection
才是正确的选择。它就是为这种情况而设计的。@Superbest您不能重写Add,因为Add不是虚拟的,您只能隐藏它。“这真是糟糕的设计。”-为什么?@Superbest,因为对基类进行强制转换可以避免隐藏。违反LSP,您不再有一致的实现(
IList.Add
List.Add
MyList.Add
不一致)等等。圆椭圆这样的东西不违反LSP吗?@Superbest:是的。还有很多其他的事情。你的观点是什么?
class MyCollection:Collection<T>
{
    private void ValidateItem(T item)
    {
       if(item is invalid)
         throw new ArgumentException("Item is invalid");
    }

    protected override InsertItem(int index, T item)
    {
        ValidateItem(item);
        base.InsertItem(index, item);
    }

    protected override SetItem(int index, T item)
    {
        ValidateItem(item);
        base.SetItem(index, item);
    }
}