C# 为什么可以';t我使用HashSet<;字符串>;要实现IEnumerable<;字符串>;接口属性?

C# 为什么可以';t我使用HashSet<;字符串>;要实现IEnumerable<;字符串>;接口属性?,c#,interface,hashset,C#,Interface,Hashset,我想知道为什么我不能使用HashSet来实现IEnumerable接口属性 下面的代码给了我一个编译错误,错误如下: “查找”未实现接口成员“ILookups.LastNames”。 “Lookups.LastNames”无法实现“ILookups.LastNames”,因为它 没有匹配的返回类型 'System.Collections.Generic.IEnumerable' …而且它看起来确实实现了IEnumerable哈!这并不重要,只是烦人,因为解决方法很长,感觉像是语言的一个坏特性,非

我想知道为什么我不能使用
HashSet
来实现
IEnumerable
接口属性

下面的代码给了我一个编译错误,错误如下:

“查找”未实现接口成员“ILookups.LastNames”。 “Lookups.LastNames”无法实现“ILookups.LastNames”,因为它 没有匹配的返回类型 'System.Collections.Generic.IEnumerable'

…而且它看起来确实实现了
IEnumerable
哈!这并不重要,只是烦人,因为解决方法很长,感觉像是语言的一个坏特性,非常呃..Java语言?(呵呵!)。(我会在工作完成后尽快在这里发布,以防我错过了一个技巧)。如果有人有一个答案或更好的方法来做这件事,或者为什么会这样,那将是最感激的

txs

艾伦

更新:1.1.15大多数评论写完后1天,所以请少吃一点盐

re:re:“即使B继承/实现了a,也不能用另一个返回B的属性来实现声明为返回a的属性。”我不认为这是完全正确的,因为下面的代码编译得非常好;啊

 void Main()
{
    var r = new PersonRepo();
    Console.WriteLine(r.GetPerson(2).Name);
}

public class PersonRepo : IPersonRepo
{
    public Person GetPerson(int id)
    {
        var m = new Manager()
        { 
            Department = "department" + id.ToString(), 
            Name = "Name " + id.ToString()
        };
        return m;
    }
}

public interface IPersonRepo
{
    Person GetPerson(int id);
}

public class Person 
{
    public string Name { get; set;}
}

public class Manager : Person
{
    public string Department { get; set; }
}

我刚刚看到了我的错误,如果您将
Person-GetPerson(int-id)
更改为
Manager-GetPerson(int-id)
您将得到一个编译错误,这实际上是有意义的!好吧,我想这件事已经做完了-要实现接口,成员签名必须与接口中声明的完全相同。即使
B
继承/实现
a
时,也不能用另一个返回
B
的属性来实现声明为返回
a
的属性

您可以明确地实现该成员并将其路由到您的属性:

public class Lookups : ILookups
{
    public HashSet<string> FirstNames { get; set; }

    IEnumerable<string> ILookups.FirstNames { get { return this.FirstNames; } }
}
公共类查找:ILookups
{
公共哈希集名{get;set;}
IEnumerable ILookups.FirstNames{get{返回this.FirstNames;}}
}
为什么需要这样做?考虑下面的代码:

var lookups = (ILookups)new Lookups();
// assigning List<string> to ILookups.FirstNames, which is IEnumerable<string>
lookups.FirstNames = new List<string>();
var lookups=(ILookups)new lookups();
//将列表分配给ILookups.FirstNames,它是IEnumerable
lookups.FirstNames=新列表();

您希望如何解决这个问题?这是完全有效的代码,但是通过
查找
实现,您刚刚将
列表
分配给了
哈希集
!方法和/或仅getter属性并不重要,但可能只是为了一致性?

实现接口成员签名必须与接口中声明的完全相同。即使
B
继承/实现
a
时,也不能用另一个返回
B
的属性来实现声明为返回
a
的属性

您可以明确地实现该成员并将其路由到您的属性:

public class Lookups : ILookups
{
    public HashSet<string> FirstNames { get; set; }

    IEnumerable<string> ILookups.FirstNames { get { return this.FirstNames; } }
}
公共类查找:ILookups
{
公共哈希集名{get;set;}
IEnumerable ILookups.FirstNames{get{返回this.FirstNames;}}
}
为什么需要这样做?考虑下面的代码:

var lookups = (ILookups)new Lookups();
// assigning List<string> to ILookups.FirstNames, which is IEnumerable<string>
lookups.FirstNames = new List<string>();
var lookups=(ILookups)new lookups();
//将列表分配给ILookups.FirstNames,它是IEnumerable
lookups.FirstNames=新列表();

您希望如何解决这个问题?这是完全有效的代码,但是通过
查找
实现,您刚刚将
列表
分配给了
哈希集
!这与方法和/或仅getter属性无关,但可能只是为了一致性?

它告诉您问题中包含的错误消息中的确切原因:
,因为它没有匹配的返回类型System.Collections.Generic.IEnumerable。
实际上,Java允许这样做。哈哈!太棒了,向Java开发者道歉!不错。@kyle在对下面答案的评论中有一个很好的观点,说接口不应该有setter。很多讨论都围绕着二传手在场这一事实展开。从界面中删除setter,代码将更准确地反映我的问题的意图,但从根本上说,这将是一个全新的问题,所以这里只参考Kyle的评论。感谢大家提供了快速而详细的回复,非常棒的东西。它告诉您在问题中包含的错误消息中的确切原因:
,因为它没有匹配的返回类型System.Collections.Generic.IEnumerable。
实际上,Java允许这样做。哈哈!太棒了,向Java开发者道歉!不错。@kyle在对下面答案的评论中有一个很好的观点,说接口不应该有setter。很多讨论都围绕着二传手在场这一事实展开。从界面中删除setter,代码将更准确地反映我的问题的意图,但从根本上说,这将是一个全新的问题,所以这里只参考Kyle的评论。谢谢大家快速详细的回复,很棒的东西。Eeeeek!那太可怕了!好吧,当然,我意识到这是一个非常紧凑的C#解决方案,我真的很感谢您的及时准确的回复。来自我的“史莱克”,是我意识到我的爱子C#已经破碎!抽噎(他一边说,一边口齿不清地翻阅F#Functional programming。嗯,是时候转向一种语言了,在这种语言中,所有代码都属于你,每一行代码都表达了你的意图。仅仅因为编译器无法推断要做什么,就不得不写几行代码似乎是错误的。)HashSet类型设置器未实现IEnumerable类型设置器接口!IEnumerable setter允许设置列表、字典或任何内容,但HashSet类型不支持这种设置。接口需要100%匹配的实现,这是很有道理的。我想解释一下,如果某个东西需要
IList
,那么意图是您可以自由使用任何