9

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?

2
  • Does SQLServerRestorer implement any interface that has the ConnectionString declared in it? Commented Feb 7, 2012 at 15:37
  • No, the ConnectionString property is declared as a public property on the class SQLServerRestorer. Commented Feb 14, 2012 at 7:11

4 Answers 4

16

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes this is excactly the behavior i'm experiencing :( I will have a look at the Decorator pattern.
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.
@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.
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.
4

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.

Comments

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; } } 

Comments

0

You want to override the method, but it seems you can't:

Use the override modifier to modify a method, a property, an indexer, or an event. An override method provides a new implementation of a member inherited from a base class. The method overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.

You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.

Although others point out that you can use the new modifier, I don't think that will serve you well:

It is an error to use both new and override on the same member because the two modifiers have mutually exclusive meanings. The new modifier creates a new member with the same name and causes the original member to become hidden. The override modifier extends the implementation for an inherited member.

To me, that sounds like any code using the base (3rd party) type will invoke the old property - this is a mess just waiting to happen!

6 Comments

That's what the new modifier is used for in C#.
Really the OP wants to replace the property. And the OP isn't using override as it stands.
@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.
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.
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...
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.