Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 685
Sarah Vessels Avatar asked Jan 27 '10 16:01

Sarah Vessels


1 Answers

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.

like image 150
Adam Robinson Avatar answered Sep 30 '22 00:09

Adam Robinson