How will encapsulation help when making changes in code and from its
rippling effects. For a data member, if I change its type from int to
float, (even if I am exposing this using property) I will need to
change variable type where I am using already using this code.
The benefit of encapsulation is that it lets you change the internal implementation without breaking client code. It doesn't protect you if you decide that you need to change the interface to your code, but that's a different matter.
Example: Say you have a value representing the price per unit of some commodity. The price is expressed in cents, and because you don't deal in fractional cents you decided to make the property an integer (I'll use C here because I'm not very familiar with C#):
int _price
int pricePerUnit(void) {
return _price;
}
int priceForUnits(int units) {
return units * _price;
}
That all works out fine until one day when somebody notices that your firm is losing a lot of money due to rounding errors. Many of the commodities that you track are bought and sold in lots of many thousands of units, so you need to start tracking the price to an accuracy of at least 0.001 cent. Because you were smart enough to encapsulate the price instead of letting clients access it directly, you can make that change pretty quickly:
double _dprice
int pricePerUnit(void) {
return (int)_dprice;
}
int priceForUnits(int units) {
return (int)(units * _dprice);
}
The interface that clients use to obtain prices stays the same, but the data they get back is now more accurate. If the price per unit is $1.001, priceForUnits(1000000)
will now return a price that's $1000 greater than before. That happens even though you haven't changed the interface to your system at all, and you therefore haven't broken any client code.
Now, that may not always be all that you need to do. Sometimes you'll need to change or augment your interface so that you can report the price more accurately to clients, too:
double pricePerUnit() {
return _dprice;
}
A change like that will break client code, so you might instead keep the old interface and provide a newer, better routine:
int pricePerUnit() {
return (int)_dprice;
}
double accuratePricePerUnit() {
return _dprice;
}
You and the rest of your team can then embark on the process of converting all the clients of your system to use the newer, better accuratePricePerUnit()
. The client code will get more accurate as you make progress on that task, but even the old stuff should continue to work as well as it did in the past.
Anyway, the point is that encapsulation lets you change the way the internals work while presenting a consistent interface, and that helps you make useful changes without breaking other code. It doesn't always protect you from having to update other code, but it can at least help you do that in a controlled manner.
What is a Date?
Let's say It's noon at your local region. You'll look at your clock and see something like 22/03/2017 12:00. You could say easily that this is the current date for everyone else in the world, right?
Well, not really. Chances are, if you are in London, or say, Russia, or the United States, your clock isn't really correct regarding those places. Your clock is marking the wrong time for the rest of the world, and for some places even the wrong date. When you talk about "the world", having a date without a time makes little to no sense once you start considering people outside your timezone. Just think how annoying it is to go to a foreigner website and seeing that, somehow, the user generated content there is coming from the future. That's what happens when you don't take into account timezones!
That's where C# DateTime goes in.
DateTime isn't the usual simple date you may need for local, just-my-company software. It is a somewhat powerful data structure that had the intent to be able to provide Universal Coordinated Time to any app. The magic part of the DateTime structure is that, with minor fiddling, you can make it display the correct DateTime for every single place in the world.
The idea behind DateTime was to provide not a simple Date object, but something you could use to represent dates all over the world, even with different Time Zones. It was made thinking in global applications, and thus it was designed with a bunch of extra functionalities that may not have apparent utility at first glance, but nevertheless can save a lot of time from people developing applications that will have to deal with variable time zones.
It is far from perfect, yes, but it does what it was meant for - representing Time in a universal, and somewhat portable, way.
So, in a sense, when using C# you are forced to consider times when developing your app, not only dates. And, really, that's a good thing - a DateTime is a reference point in time relative to something, and when you change your point of reference, the value for that DateTime must act accordingly.
To be totally fair, I think C# is one of the languages that got this thing right. You can have a Time interval without a date (TimeSpan is there for that), but you can't really have a meaningful date on a global scope without a reference frame and a time attached to it. I didn't like DateTime at all when I first met the language, but after having to develop an App with multiple timezones I understood why this design choice was actually a smart one.
Best Answer
I think a general pattern for this is as follows
and then many:
So you can make a IDataConverter for whatever types you want, and the Converter has a list of these which it loops through, calling CanConvert. If that returns true, it calls the Convert Function and returns the result
Edit: as you can see shoehorning in the generic type in there is tricky. You are probably better using the same pattern but just returning object