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 { }
}