Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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#属性在派生类中不可用_C#_Inheritance_Interface_Class Hierarchy_Explicit Interface - Fatal编程技术网

C#属性在派生类中不可用

C#属性在派生类中不可用,c#,inheritance,interface,class-hierarchy,explicit-interface,C#,Inheritance,Interface,Class Hierarchy,Explicit Interface,我不知道发生了什么事。我有以下基类: public class MyRow : IStringIndexable, System.Collections.IEnumerable, ICollection<KeyValuePair<string, string>>, IEnumerable<KeyValuePair<string, string>>, IDictionary<string, string> {

我不知道发生了什么事。我有以下基类:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> IDictionary<string, string>.Keys { }
}
公共类MyRow:IStringIndexable,System.Collections.IEnumerable,
I收集,
我数不清,
词典
{
ICollection IDictionary.Keys{}
}
然后我有一个派生类:

public class MySubRow : MyRow, IXmlSerializable, ICloneable,
    IComparable, IEquatable<MySubRow>
{
    public bool Equals(MySubRow other)
    {
        // "MyRow does not contain a definition for 'Keys'"
        foreach (string key in base.Keys) { }
    }
}
公共类MySubRow:MyRow、IXmlSerializable、ICloneable、,
可比
{
公共布尔等于(MySubRow其他)
{
//“MyRow不包含“键”的定义”
foreach(base.Keys中的字符串键){}
}
}

为什么我会犯这样的错误?“'MyNamespace.MyRow'不包含'Keys'的定义。”。这两个类都位于
MyNamespace
命名空间中。我尝试访问
this.Keys
base.Keys
,但在
MySubRow
中两者都不起作用。我尝试在
MyRow
中将
Keys
属性标记为
public
,但得到了“修饰符'public'对此项无效”,我认为这是因为有必要实现一个接口。

您正在显式实现
Keys
属性。如果要使该成员可公开访问(或受保护),请将
IDictionary.Keys
更改为
Keys
,并在其前面添加适当的可见性修饰符

public ICollection<string> Keys { ... }
更多信息

(从您的评论来看,您似乎熟悉这一区别,但其他人可能不熟悉)

C#接口实现可以通过两种方式完成:隐式或显式。让我们考虑一下这个接口:

public interface IMyInterface
{
    void Foo();
}
接口只是一个契约,用于类成员必须向调用它的代码提供的内容。在本例中,我们有一个名为
Foo
的函数,它不接受任何参数,也不返回任何内容。隐式接口实现意味着您必须公开与接口上成员的名称和签名匹配的
public
成员,如下所示:

public class MyClass : IMyInterface
{
    public void Foo() { }
}
这满足了接口,因为它在类上公开了一个与接口上的每个成员匹配的
public
成员。这是通常的做法。但是,可以显式地实现接口,并将接口功能映射到
私有
成员:

public class MyClass : IMyInterface
{
    void IMyInterface.Foo() { }
}
这将在
MyClass
上创建一个私有函数,只有外部调用方在引用
IMyInterface
的实例时才可以访问该函数。例如:

void Bar()
{
    MyClass class1 = new MyClass();
    IMyInterface class2 = new MyClass();

    class1.Foo(); // works only in the first implementation style
    class2.Foo(); // works for both
}

显式实现总是私有的。如果要在类之外公开它,则必须创建另一个成员并公开该成员,然后使用显式实现调用另一个成员。这通常是为了使一个类可以实现接口而不会弄乱它的公共API,或者如果两个接口公开了具有相同名称的成员。

由于要显式实现IDictionary接口,首先必须将
This
转换为
IDictionary

public bool Equals(MySubRow其他)
{
foreach(字符串键在((IDictionary)this.Keys){}
}

我相信Jared和Adam都是正确的:属性是在基类上实现的显式属性,导致它不是公共的。您应该能够将其更改为隐式实现并使其满意:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> Keys { }
}
公共类MyRow:IStringIndexable,System.Collections.IEnumerable,
I收集,
我数不清,
词典
{
i收集键{}
}

受保护的
将允许继承类看到它,但OP正在访问成员,而不是尝试实现其他类it@Jared例如看他的第一节课。属性是在那里实现的,它是显式实现的。@Adam,明白了,错过了显式implementation@Adam:她的第一节课。:)谢谢,把它改成简单的
public-ICollection-Keys
就行了。@Sarah:真是罪过!我没费心读手术的名字,谢谢。我最终删除了
MyRow
中的显式接口声明。现在它只是
public ICollection key
并调用
base.key
就行了。@Sarah,在某些情况下,你必须使用@dtb建议的方法,因为多个接口将定义相同的方法名…@Rob:这实际上是我过去所做的,然后,作为重构的结果,减少了类实现的接口,因此不再需要显式实现。我无法将其标记为
public
protected
,因为我正在显式实现接口。在显式实现它时,添加类似于
public
的修饰符会导致单独的编译错误。我最终使它成为一个隐式实现,然后添加了
public
public ICollection键
。我使它隐式且
public
,是的。
void Bar()
{
    MyClass class1 = new MyClass();
    IMyInterface class2 = new MyClass();

    class1.Foo(); // works only in the first implementation style
    class2.Foo(); // works for both
}
public bool Equals(MySubRow other)
{
    foreach (string key in ((IDictionary<string,string>)this).Keys) { }
}
public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> Keys { }
}