• 0

[C#] Hiding Base Class Members


Question

If you don't want to read all this, look at the code (notice the different return types) and read below it :p

Basically, I'm being very anal and don't want any compiler warnings at all :p I've been getting this annoying level 2 warning in VS.NET saying that my inheriting classes are hiding a property, and I need to use the new keyword. The thing is, I don't want to use the new keyword because I want the inherited method to always handle it, and the base method to only be there as a requirement for all inherited classes. Some of you may know what I'm getting at already, but if not, here's what's going on:

I have a RegistryValue class (my own) and several other classes such as StringValue, DwordValue, MultiStringValue, etc. The base class, RegistryValue, has an abstract property called Data that returns an object (because a registry value can contain numerous types of objects). The inheriting classes also have a Data property that currently hides this base property, and returns a value of the correct type (string for StringValue, int for DwordValue, string[] for MultiStringValue, etc). This works great, but VS.NET wants me to declare the Data property in the inherited members with the new keyword, giving any client apps access to both the base and inherited properties. But I don't want that :p I say cast it to an object yourself if that's what you need, but I can't fathom why you would... I would just remove the base property, but in the future someone may add additional types of RegistryValues, and I think those new types should be required to have this property. So how do I do this? :huh: Here's some sample code if anyone needs it:

public abstract class RegistryValue

{

public object Data

{

? get

? {

?? return this.data;

? }

? set

? {

?? this.data = value;

? }

}

}

public class DwordValue : RegistryValue

{

public int Data

{

? get

? {

?? return (int)this.data;

? }

? set

? {

?? base.data = (object)value;

? }

}

}[/quoteSo how do I get around this compiler warning while still requiring all inherited classes to have a Data property, but allow that inherited property to return any type it wants?y:huh: it wants? :huh:

Sorry for the long-winded post, I hope I didn't waste too much o:blush:e's time :blush:

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

It compiles, but I get a similar warning telling me to add the override keyword to the other properties, OR add the new keyword. Adding the override keyword, however, causes a compile error saying I can't change the return type when overriding a base class member, which is what I need to do... :hmmm:

Darn this is annoying :angry:

Link to comment
Share on other sites

  • 0

Ah... yeah... :huh:

I'm not seeing where you're getting that the client would have access to the base class's property. If the client instatiates a DwordValue, that's the property they'll see unless they cast their instance up to a RegistryValue.

Use the new keyword and it should work just fine.

Link to comment
Share on other sites

  • 0

The best way to do what you want would be to create an interface with the RegistryValue property in it. Your inherited class should inherit from both your base class and the interface. Though by itself that doesn't necessarily force anyone to use RegistryValue in their inherited class, but you can set your program up so that it will refuse to load a class unless it inherits from that interface.

Link to comment
Share on other sites

  • 0

You could of course just use the new keyword as weenur said. All that does is takes over the base property so whenever you access it through this.Property you will get the value defined in your class, and if you do base.Property it will return whatever the base class returns.

Dan

EDIT: You could also make the property abstract... that should work for what you want?

EDIT2: hmm actually that wont work.. you wont be able to change the return type.. DannySmurf's way is probably best then I suppose, or just use the new keyword.

Edited by dannyres
Link to comment
Share on other sites

  • 0
Ah... yeah... :huh:

I'm not seeing where you're getting that the client would have access to the base class's property. If the client instatiates a DwordValue, that's the property they'll see unless they cast their instance up to a RegistryValue.

Use the new keyword and it should work just fine.

OK, but my own client app I'm creating along side this project will be using arrays of RegistryValues that can be of any type (ie. StringValue, DwordValue, etc)... That's where I want to make sure the correct method/property is used.

Link to comment
Share on other sites

  • 0
You could of course just use the new keyword as weenur said.  All that does is takes over the base property so whenever you access it through this.Property you will get the value defined in your class, and if you do base.Property it will return whatever the base class returns.

Yes, yes, and that's exactly what I don't want. I want a StringValue's Data property to always use a string value, and not a System.Object value like the RegistryValue class does... Same for dwords (System.Int32), binary values (System.Byte[]), etc. Client code may cast any type of Value as a RegistryValue (the base class) for simple foreach loops or something, and herein lies the problem...

Link to comment
Share on other sites

  • 0
The best way to do what you want would be to create an interface with the RegistryValue property in it. Your inherited class should inherit from both your base class and the interface. Though by itself that doesn't necessarily force anyone to use RegistryValue in their inherited class, but you can set your program up so that it will refuse to load a class unless it inherits from that interface.

Could you elaborate on this? I've never used interfaces, but I'm far more familiar with them than I am delegates ;)

I thought that any members in the interface couldn't have their return type changed? If they can, then that will work great :woot: But I'm pretty sure I read they can't be :/

Link to comment
Share on other sites

  • 0

No, their return type can't be changed. But then, an inherited member's return type has to match up with its base member's return type too, so even doing the hiding-the-base member thing won't work for you, if that has to be one of the criteria.

(I just double-checked this in case I was wrong... if you change the return type in the inherited class you get "DoSomething() return type must be 'valuetype' to match overriden member DoSomething()" when you try to compile)

Two things you could do: Declare the return type as Object, which can be casted to anything (downside: you have to use the 'is' operator or GetType() in the calling code to find out what the Object is when it is returned), or declare multiple functions so that you cover every possible return type (downside: if you're using an interface, all functions must be implemented).

Declaring an interface is simple. Just members with no impelementation:

public interface MyInterface
{
   String SomeProperty {get; set;}
   int Function1();
   double Function2(int a, int b);
}

You inherit from it just like from a base class. The caveat is that you MUST implement all members of the interface in your inherited class (it's not optional as it is with a base class):

public class MyClass : MyInterface
{
   public MyClass() {}

   public String SomeProperty
   {
      get { ... }
      set { ... }
   }

   public int Function1()
   {
   }

   public double Function2()
   {
   }
}

That's pretty much it. Preventing classes that do not inherit from your interface from being loaded (I'm assuming this is some sort of a plugin architecture) is fairly simple if you know .NET reflection.

Link to comment
Share on other sites

  • 0

OK, thanks danny (Y)

I'm starting to think that what I want isn't exactly possible, so I think I'm just going to add the new keyword to all derived properties and have the two seperate properties (base and inherited). All client code will have to understand that when dealing with RegistryValue objects (as opposed to their exact type, because RegistryValues are abstract) will always return their data as a System.Object instead of its exact type :(

Well that would happen anyway... :ermm: I guess it doesn't matter that much afterall... Oh well, thanks again guys, and sorry for wasting your time :pinch:

Link to comment
Share on other sites

  • 0

I seel what danny's saying, but I still think you run into the same problem regarding return type. You can't change the signature of an interface in the implementer. So essentially, you're stuck with the base type until you down-cast.

Hehe... too late. :D

Yeah, what he said!

Link to comment
Share on other sites

  • 0

Yeah, there really isn't a satisfactory solution to this particular problem (I've wanted to hide base class implementation more than once, though for a different reason). Inheritance -- with third-party additions in mind -- is just generally more work than it really should be.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.