views:

91

answers:

6

I got a requirement in my project to add another property to some class. Now I want to avoid changing the class because I figured it shouldn't be aware that he has this property (this property only has significance in the context of this project).

The way I thought to accomplish this was (Please critic this because I wanna know if there are simpler ways of doing this)

  1. Adding a new singleton class that has a mapping between objects of my class and the type of the property I wanted to add
  2. adding in this class an extension method (extension property?) to access the mapping and fetch the property.

Is there a simpler alternative? Is this just unnecessary complexity? Maybe I should just add a new property to my class?

Thanks!

A: 

An extension method makes sense and it's also relatively simple.

[visibility] [type] [methodName](this [class to extend] c, ... more args if necessary)
{
....
}
Chad
But a static extension method doesn't work like a class property.
Dan Diplo
Extension methods are static, and have to be members of a static class. That limits their ability to hold state information of any kind; it's generally best practice to treat extension methods as stateless (i.e., they can't act like properties).
Cylon Cat
+2  A: 

Why do you say "not inheritance"? Surely the way to do this, if you don't want to alter the original class, would be to inherit from the original class and then add your property to the derived class?

BTW, there are only extension methods, not properties, so you can't do it via property.

Dan Diplo
I can imagine many cases where inheritance is not possible or not meaningfull, because of the fact that the object creation can not be influenced (e.g. when working with some ORMs). Composition is often an option.
HCL
A: 

Adding a property doesn't break the class's interactions with existing clients, so that really seems the "simplest" approach.

More important, though, is the function of the new property. Is it logically part of the existing class? Change the class. If not, then an extension method might be preferable, but the problem then becomes the visibility of the extension method, and scope of its clients.

As always, complexity is the enemy. In this case, it sounds as though the singleton is a very complex solution, and the extension method is hit-and-miss, depending on scope and visilbity issues. Changing the class is simplest, and will probably make long-term maintenance much easier.

UPDATE: Note that extension methods are static, and that makes it pretty difficult for the extension method to hold data of any time, as a property would be exptected to do.

SECOND UPDATE: If you have access to the source for the class, consider making it a partial class, and put your new property in a separate file, but part of the same partial class. This keeps it separate from the main body of the class for maintenance purposes, and will work with most ORMs. However, there is a restriction that the partial class members have to be in a single assembly.

Cylon Cat
+2  A: 

I would suggest the DECORATOR pattern. I know you say you don't want to use inheritence, but sometimes it's cleaner to do so. The pattern only uses inheritance to define the interface.

Jerod Houghtelling
+4  A: 

The design you've described is actually the one used by Microsoft to implement the DependencyProperty system and, in particular, Attached Properties, though in the greater context of a binding framework. That said, using a dictionary with 'attached' data is a very typical solution when you need to tag a class with additional context for a particular use, but don't want to modify the class.

Dan Bryant
A: 

Define a Nullable values with their Properties(while the Property has significance only for this project)

your major problem is that you don't want to change the class itself because this requirement is ONLY for 1 project (build), i think you are considering SOLID priniciples, one of these principles is OCP (Open-Closed Principle), that is,

your Entity must be open for extension but closed for modification

Saeedouv