简体   繁体   English

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

[英]C# property not available in derived class

I'm not sure what's going on. 我不确定发生了什么。 I have the following base class: 我有以下基类:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> IDictionary<string, string>.Keys { }
}

And then I have this derived class: 然后我有这个派生类:

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

Why do I get that error? 为什么我会收到这个错误? "'MyNamespace.MyRow' does not contain a definition for 'Keys'". “'MyNamespace.MyRow'不包含'Keys'的定义”。 Both classes are in the MyNamespace namespace. 这两个类都在MyNamespace命名空间中。 I tried accessing this.Keys and base.Keys and neither works from within MySubRow . 我试过访问this.Keysbase.Keys并且都不能在MySubRow I tried marking the Keys property as public in MyRow but got "The modifier 'public' is not valid for this item", I think because it's necessary to implement an interface. 我尝试在MyRow中将Keys属性标记为public ,但得到“修饰符'public'对此项无效”,我认为因为有必要实现一个接口。

You're implementing the Keys property explicitly. 您正在显式实现Keys属性。 If you want to make that member publicly accessible (or protected ), change IDictionary<string, string>.Keys to Keys and add the appropriate visibility modifier in front of it. 如果要使该成员可公开访问(或protected ),请将IDictionary<string, string>.Keys更改为Keys并在其前面添加适当的可见性修饰符。

public ICollection<string> Keys { ... }

or 要么

protected ICollection<string> Keys { ... }

You could reference base as an instance of IDictionary<string, string> as well: 您可以将base引用为IDictionary<string, string>的实例:

((IDictionary<string, string>)base).Keys

More Information 更多信息

(Judging by your comments you appear to be familiar with the distinction, but others may not be) (根据你的评论,你似乎熟悉这种区别,但其他人可能不是)

C# interface implementation can be done two ways: implicitly or explicitly. C#接口实现可以通过两种方式完成:隐式或显式。 Let's consider this interface: 让我们考虑一下这个界面:

public interface IMyInterface
{
    void Foo();
}

An interface is just a contract for what members a class must make available to code that is calling it. 接口只是一个类,它必须为调用它的代码提供哪些成员。 In this case, we have one function called Foo that takes no parameters and returns nothing. 在这种情况下,我们有一个名为Foo函数,它不带任何参数并且不返回任何内容。 An implicit interface implementation means that you must expose a public member that matches the name and signature of the member on the interface, like this: 隐式接口实现意味着您必须公开与接口上成员的名称和签名匹配的public成员,如下所示:

public class MyClass : IMyInterface
{
    public void Foo() { }
}

This satisfies the interface because it exposes a public member on the class that matches every member on the interface. 这满足了接口,因为它在类上公开了与接口上的每个成员匹配的public成员。 This is what is usually done. 这就是通常所做的事情。 However, it is possible to explicitly implement the interface and map the interface function to a private member: 但是,可以显式实现接口并将接口函数映射到private成员:

public class MyClass : IMyInterface
{
    void IMyInterface.Foo() { }
}

This creates a private function on MyClass that is only accessible to outside callers when they are referring to an instance of IMyInterface . 这会在MyClass上创建一个私有函数,只有当外部调用者引用IMyInterface的实例时才能访问它。 For instance: 例如:

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

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

Explicit implementations are always private. 显式实现始终是私有的。 If you want to expose it outside of the class you'll have to create another member and expose that, then use the explicit implementation to call the other member. 如果要在类之外公开它,则必须创建另一个成员并公开它,然后使用显式实现来调用其他成员。 This is usually done so that a class can implement interfaces without cluttering up its public API, or if two interfaces expose members with the same name. 通常这样做是为了使类可以实现接口而不会混乱其公共API,或者如果两个接口公开具有相同名称的成员。

Since you're implementing the IDictionary<TKey,TValue> interface explicitly, you first have to cast this to IDictionary<string,string> : 既然你实施的IDictionary <TKEY的,TValue>中接口明确,你首先要投thisIDictionary<string,string>

public bool Equals(MySubRow other)
{
    foreach (string key in ((IDictionary<string,string>)this).Keys) { }
}

I believe both Jared and Adam are correct: the property is explitcity implemented on the base class, resulting in it not being public. 我相信Jared和Adam都是正确的:该属性是在基类上实现的,它导致它不公开。 You should be able to change it to an implicit implementation and make it happy: 您应该能够将其更改为隐式实现并使其满意:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> Keys { }
}

protected将允许继承类来查看它,但没有其他类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM