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

发布于 2024-08-19 08:10:29 字数 956 浏览 5 评论 0原文

我不确定发生了什么事。我有以下基类:

public class MyRow : IStringIndexable, System.Collections.IEnumerable,
    ICollection<KeyValuePair<string, string>>,
    IEnumerable<KeyValuePair<string, string>>,
    IDictionary<string, string>
{
    ICollection<string> IDictionary<string, string>.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) { }
    }
}

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

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'". Both classes are in the MyNamespace namespace. I tried accessing this.Keys and base.Keys and neither works from within 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不喜欢何必死缠烂打 2024-08-26 08:10:29

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

public ICollection<string> Keys { ... }

或者

protected ICollection<string> Keys { ... }

您也可以将 base 引用为 IDictionary 的实例:

((IDictionary<string, string>)base).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,或者如果两个接口公开具有相同名称的成员。

You're implementing the Keys property explicitly. 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.

public ICollection<string> Keys { ... }

or

protected ICollection<string> Keys { ... }

You could reference base as an instance of IDictionary<string, string> as well:

((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. 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. 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 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. This is what is usually done. However, it is possible to explicitly implement the interface and map the interface function to a private member:

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. 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.

睫毛上残留的泪 2024-08-26 08:10:29

由于您正在实现 IDictionary;显式接口,首先必须将 this 转换为 IDictionary

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

Since you're implementing the IDictionary<TKey,TValue> interface explicitly, you first have to cast this to IDictionary<string,string>:

public bool Equals(MySubRow other)
{
    foreach (string key in ((IDictionary<string,string>)this).Keys) { }
}
写下不归期 2024-08-26 08:10:29

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

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

I believe both Jared and Adam are correct: the property is explitcity implemented on the base class, resulting in it not being public. 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 { }
}
黯然#的苍凉 2024-08-26 08:10:29

protected 将允许继承类看到它,但不允许其他类看到

protected will allow inheriting classes to see it, but no other class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文