Override a public property from a derived class

21,155

Solution 1

As others have pointed out you can use the new keyword to hide the base member property. Note however that this doesn't magically turn the ConnectionString property into a polymorphic function, i.e. if you have something like this:

public class A 
{
    public string CString { get { return "a"; } }
}

public class B : A
{
    public new string CString { get { return "b"; }}
}

and you do this:

A a = new B();

Console.WriteLine(a.CString);

Then you will still see an "a" printed to the console. In fact the new keyword just stops the compiler from issuing a warning regarding the hiding of the member of the base class. It doesn't change the behavior of the code at runtime.

You can try to use a Decorator pattern and wrap the SQLServerRestorer, but if that doesn't work either, you are out of luck I am afraid.

Solution 2

You will need to indicate that you want to 'replace' this property, using new:

public new string ConnectionString
{
   get { return "My custom connection string"; }
}

Obviously you can extend that to implement your own set, even if just to utilise auto-implemented accessors. Documentation on 'versioning' with new can be found here, but specifically:

Using the new keyword tells the compiler that your definition hides the definition contained in the base class. This is the default behavior.

Solution 3

You're looking for the new keyword:

public class SqlServerRestorerExstension : SQLServerRestorer
{
    public SqlServerRestorerExstension(string dbServer, string dbName, string dbFilePath, string dbDataFileName, string dbLogFileName, bool detachOnFixtureTearDown, string connectionstring) : base(dbServer, dbName, dbFilePath, dbDataFileName, dbLogFileName, detachOnFixtureTearDown)
    {
        ConnectionString = connectionstring;
    }

    public new string ConnectionString { get; private set; }
}
Share:
21,155
peterbf
Author by

peterbf

Updated on February 08, 2020

Comments

  • peterbf
    peterbf about 4 years

    In an old project we are using a third party assembly with a class that has a property with some hardcoded information:

    public string ConnectionString
    {
        get
        {
            string[] fullDbName = new string[5];
            fullDbName[0] = "Data Source=";
            fullDbName[1] = this.dbServer;
            fullDbName[2] = ";Initial Catalog=";
            fullDbName[3] = this.FullDbName;
            fullDbName[4] = ";Integrated Security=SSPI;Pooling=false";
            return string.Concat(fullDbName);
        }
    }
    

    I need to be able to construct the connection string my self. So I have tried to make a derived class that hides the original property, but it does not seem to work:

    public class SqlServerRestorerExstension : SQLServerRestorer
    {
        public SqlServerRestorerExstension(string dbServer, string dbName, string dbFilePath, string dbDataFileName, string dbLogFileName, bool detachOnFixtureTearDown, string connectionstring) : base(dbServer, dbName, dbFilePath, dbDataFileName, dbLogFileName, detachOnFixtureTearDown)
        {
            ConnectionString = connectionstring;
        }
    
        public string ConnectionString { get; private set; }
    }
    

    Is it possible do achive this in any way when I don't have acces to the third party code?

  • Yuck
    Yuck about 12 years
    That's what the new modifier is used for in C#.
  • Grant Thomas
    Grant Thomas about 12 years
    Really the OP wants to replace the property. And the OP isn't using override as it stands.
  • Yuck
    Yuck about 12 years
    @Mr.Disappointment exactly right - the OP wants to change the behavior of an object that he doesn't have the source for. new will do just that. He's not trying to combined override and new as suggested here.
  • supercat
    supercat about 12 years
    It's too bad there's no way to declare an "overrides" member and a "new" member with the same name in the same class; such an ability would allow a read-only property to be overridden with a new implementation and also shadowed by a read-write one, or allow a base-class function that returns a base type, to be overridden with a derived-class function that returns a derived type. To be sure, if other means existed for doing such things, those might be just as good, but requiring an extra level to the inheritance hierarchy to accomplish them seems ugly.
  • peterbf
    peterbf about 12 years
    Yes this is excactly the behavior i'm experiencing :( I will have a look at the Decorator pattern.
  • darkAsPitch
    darkAsPitch about 12 years
    maybe I'm understanding something wrong here, but if you pass this new object into a method expecting the base class, then won't the old property be retrieved? That is, new won't be polymorphic? This is an issue...
  • peterbf
    peterbf about 12 years
    I don't think the Decorator pattern will help, because the SQLServerRestorer-class is used to define a variable in the third party code - and therefore the original ConnectionString property will be aplied.
  • afrischke
    afrischke about 12 years
    @peterbf That's what I feared, otherwise the trick with hiding the property probably would have worked as well. You could try your luck with an aspect-oriented framework like PostSharp or Afterthought that lets you modify the properties of an existing assembly through MSIL injection.
  • peterbf
    peterbf about 12 years
    Thank you for your suggestion. I actually ended up writing my own implementation of what the third party component did - it only took a couple of hours so that seemed like the easiest solution.
  • peterbf
    peterbf about 12 years
    @Daren - Exactly - just like in the example that afrischke gave in the second answer.