Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.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# 调用IEnumerable.Cast<;T>;()将基础类型更改为其他类型,还是保留基础类型?_C#_Linq_Linq To Objects - Fatal编程技术网

C# 调用IEnumerable.Cast<;T>;()将基础类型更改为其他类型,还是保留基础类型?

C# 调用IEnumerable.Cast<;T>;()将基础类型更改为其他类型,还是保留基础类型?,c#,linq,linq-to-objects,C#,Linq,Linq To Objects,假设我有ISet\u set=newhashset() 现在如果我这样做:\u set.Cast()包含(obj,comparer)(其中T实现TInterface),我是否失去了HashSet的O(1)优势 换句话说,.Cast()ing是否将基础类型(HashSet在本例中)更改为其他类型,或者基础类型是否保留?Cast方法返回一个IEnumerable,因此Contains方法将对IEnumerable而不是HashSet进行操作。所以我认为你失去了HashSet的好处。为什么不改为在比较

假设我有
ISet\u set=newhashset()

现在如果我这样做:
\u set.Cast()包含(obj,comparer)
(其中
T
实现
TInterface
),我是否失去了
HashSet
O(1)
优势


换句话说,
.Cast()
ing是否将基础类型(
HashSet
在本例中)更改为其他类型,或者基础类型是否保留?

Cast方法返回一个IEnumerable,因此Contains方法将对IEnumerable而不是HashSet进行操作。所以我认为你失去了HashSet的好处。为什么不改为在比较中执行强制转换?

强制转换方法返回IEnumerable,因此Contains方法将对IEnumerable而不是哈希集进行操作。所以我认为你失去了HashSet的好处。为什么不改为在compared中执行强制转换?

\u set.cast()
将返回一个
IEnumerable
so
\u set.cast().Contains(obj,comparer)
不调用,而是调用扩展方法

所以很明显你不再得到
O(1)
操作了

如果需要
O(1)
,则需要再次从中创建一个
HashSet

   var newSet = new HashSet(_set.Cast<TInterface>(),comparer);
   newSet.Contains();
var newSet=newhashset(_set.Cast(),comparer);
newSet.Contains();
\u set.Cast()
将返回一个
IEnumerable
so
\u set.Cast().Contains(对象、比较器)
不调用,而是调用扩展方法

所以很明显你不再得到
O(1)
操作了

如果需要
O(1)
,则需要再次从中创建一个
HashSet

   var newSet = new HashSet(_set.Cast<TInterface>(),comparer);
   newSet.Contains();
var newSet=newhashset(_set.Cast(),comparer);
newSet.Contains();

从逻辑上讲,
哈希集
使用一个内部哈希表,该哈希表基于创建它时使用的比较器的哈希逻辑,因此当然不可能使用不同的比较器对其进行元素包含测试并期望O(1)性能


也就是说,让我们更详细地了解您的特定场景:

Cast
方法如下所示(来自参考源):

公共静态IEnumerable强制转换(此IEnumerable源代码){
IEnumerable typedSource=源为IEnumerable;
如果(typedSource!=null)返回typedSource;
if(source==null)抛出错误.ArgumentNull(“source”);
返回迭代器(源);
}
如您所见,如果源代码实现了
IEnumerable
,它只会直接返回源代码。由于
IEnumerable
是一个协变接口,因此您的用例将通过此测试(假设具体类型实现了接口类型),哈希集将直接返回——这是一件好事,因为仍然有希望使用其内部哈希表

但是,您正在使用的Contains的重载如下所示:

 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer<TSource>.Default;
            if (source == null) throw Error.ArgumentNull("source");
            foreach (TSource element in source)
                if (comparer.Equals(element, value)) return true;
            return false;
        }
公共静态bool包含(此IEnumerable源、TSource值、IEqualityComparer比较器)
{
如果(comparer==null)comparer=EqualityComparer.Default;
if(source==null)抛出错误.ArgumentNull(“source”);
foreach(源中的TSource元素)
if(comparer.Equals(element,value))返回true;
返回false;
}
如您所见,它总是通过集合循环到线性搜索,即O(n)


因此,整个操作都将是O(n)

从逻辑上讲,
哈希集
使用一个内部哈希表,该哈希表基于创建时使用的比较器的哈希逻辑,因此当然不可能使用不同的比较器对其进行元素包含测试,并期望O(1)性能


也就是说,让我们更详细地了解您的特定场景:

Cast
方法如下所示(来自参考源):

公共静态IEnumerable强制转换(此IEnumerable源代码){
IEnumerable typedSource=源为IEnumerable;
如果(typedSource!=null)返回typedSource;
if(source==null)抛出错误.ArgumentNull(“source”);
返回迭代器(源);
}
如您所见,如果源代码实现了
IEnumerable
,它只会直接返回源代码。由于
IEnumerable
是一个协变接口,因此您的用例将通过此测试(假设具体类型实现了接口类型),哈希集将直接返回——这是一件好事,因为仍然有希望使用其内部哈希表

但是,您正在使用的Contains的重载如下所示:

 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer<TSource>.Default;
            if (source == null) throw Error.ArgumentNull("source");
            foreach (TSource element in source)
                if (comparer.Equals(element, value)) return true;
            return false;
        }
公共静态bool包含(此IEnumerable源、TSource值、IEqualityComparer比较器)
{
如果(comparer==null)comparer=EqualityComparer.Default;
if(source==null)抛出错误.ArgumentNull(“source”);
foreach(源中的TSource元素)
if(comparer.Equals(element,value))返回true;
返回false;
}
如您所见,它总是通过集合循环到线性搜索,即O(n)


因此,整个操作都将是O(n)

请参阅每次我想测试是否包含某个对象时重新创建新的
哈希集
,这会造成很大的开销,但如果您想测试一行中的1000个项,则重新创建
哈希集
是一个更好的选择。不要这样认为:在最坏的情况下,迭代直到找到为止只有O(n)(如果你在第二个索引中找到它,那就是O(2)…,而在任何容器中添加N个项目总是O(N)-这总是最糟糕的情况,我想你误解了我的评论。我说如果你想检查1000个项目是否以
O(N)
*1000的顺序存在,但是如果你只创建一个
Ha