c# - 为什么我的代码需要重载 HashSet<T> 而不是 ISet<T>?

标签 c#

我有以下方法:

    private string TickIfHeadingPresent<TKey, TValue>(Dictionary<TKey, ISet<TValue>> data, TKey key, TValue value)
    {
        ISet<TValue> set;
        return data.TryGetValue(key, out set) && set.Contains(value) ? "<i class='icon-check'></i>" : String.Empty;
    }

有时我用我刚创建的对象调用方法,C# 知道我特别有一个 Dictionary<whatever, HashSet<something>>.

在那些情况下我得到错误:

cannot convert from 'System.Collections.Generic.Dictionary<string, System.Collections.Generic.HashSet<string>>' to 'System.Collections.Generic.Dictionary<string, System.Collections.Generic.ISet<string>>'

这让我很困惑,因为 HashSet<T>ISet<T> 的子集- 当然任何接受 ISet<T> 的代码不介意获得特定类型的套装吗?

根据 Visual Studio 的“修复”是添加具有更具体重载的重复方法:

    // I have no idea why this won't just hit the ISet overload...
    private string TickIfHeadingPresent<TKey, TValue>(Dictionary<TKey, HashSet<TValue>> data, TKey key, TValue value)
    {
        HashSet<TValue> set;
        return data.TryGetValue(key, out set) && set.Contains(value) ? "<i class='icon-check'></i>" : String.Empty;
    }

有什么方法可以让我只定义一次方法吗?

最佳答案

假设您有 Dictionary<string, HashSet<string>>正如你所描述的。假设您以某种方式能够将其作为 Dictionary<string, ISet<string>> 传递.如果是这种情况,您现在可以添加其他实现 ISet<string> 的对象。这本词典,不仅HashSet<string> .例如,您现在可以添加 SortedSet<string>到你的字典。但是SortedSet不是 HashSet , 也不是来自 HashSet<string> , 和你原来的 Dictionary只能包含 HashSet秒。该示例显示了为什么不允许从 Dictionary<string, HashSet<string>> 转换至 Dictionary<string, ISet<string>> .

现在,对于某些接口(interface),您不能执行此类违反类型安全的操作。例如 IEnumerable<T> .如果你有这样的方法:

 private string TickIfHeadingPresent<TKey, TValue>(IEnumerable<ISet<TKey>> data, TKey key, TValue value)

现在您可以通过 List<HashSet<string>>作为IEnumerable<ISet<string>> .您不能将新项目添加到 IEnumerable<T> ,你也不能做任何其他违反类型安全的操作。这是有保证的,因为 IEnumerable 是这样定义的:

public interface IEnumerable<out T> : IEnumerable

“out”关键字意味着 T 是协变的,编译器将确保此接口(interface)上的任何方法都不会违反这一点(基本上它不允许使用类型 T 作为任何方法的参数,只能作为返回类型)。

关于c# - 为什么我的代码需要重载 HashSet<T> 而不是 ISet<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40781052/

相关文章:

c# - 多个 ASP.NET Web 应用程序依赖于一个公共(public)基础应用程序

javascript - 如何从在客户端添加行的表中获取数据?

c# - C# 的内联服务器代码在移动到 JavaScript .js 文件时无法工作

c# - 防止单元格级制表位,但仍允许行在 WPF DataGrid 中具有制表位

c# - 如何最大限度地减少控件上的 if else 条件

c# - 出现错误 : NullReferenceException : Object reference not set to an instance of an object After pressing play game on unity

c# - 如何测试附加文件的 ASP NET ashx 处理程序

c# - 您能否使用 linq 查看两个 IEnumerables 数据是否包含任何公共(public)条目?

c# - 仅更新客户端指定值的参数

c# - 单击另一个 DataGrid 时如何失去对 DataGrid 的焦点?