Lots of sources talks about this question but I dont understand the concept very well. IDictionary is generic, its type safety etc.
When I dig into EntityFrameworkv5 I see a property that is declared as below in the LogEntry class.
private IDictionary<string, object> extendedProperties;
The question is why they prefer IDictionary against Hashtable, hence Hashtable is also takes a key as a string and a object. Only the reason is making the property polymorphic by choosing IDictionary ?
Thanks in advance.
Nowadays, there are few reasons to use Hashtable. Dictionary<> is better than it in most respects. When it's not, you can usually find another strongly typed collection that serves your purpose even better than either.
Type-safe.
None of the severe overhead of boxing and unboxing.
Implements IDictionary<>, which is very compatible with .NET and 3rd party code.
Performs better than Hashtable in many areas. See links: Link #1, Link #2.
If you're asking why type a property as IDictionary<> instead of Dictionary<>, it's for several reasons.
It is generally considered best practice to use interfaces as often as possible, instead of regular types, especially in a framework.
It is possible to change the implementation of the interface fairly easily, but it's difficult to change the nature of a concrete class without causing compatibility problems with dependent code.
Using interfaces, you can take advantage of Covariance and Contravariance.
External code is more likely to consume the more general interface IDictionary<> than the concrete class Dictionary<>. Using IDictionary<> thus lets other developers to interact better with the property.
There are tons more, probably. These are just off the top of my head.
Well yes if they had defined extendedproperies as returning hashtable then they would have been stuck with that for all time, unless they wanted to break all the code that uses extended properties.
Whole point of the returning an Interface is it doesn't matter how the method is implemented as long as it keeps doing that.
"Only reason is making the property polymorphic" misses the point, there should be very few reasons why you shouldn't do this. If you can return an interface do return an interface, most of the time that's good design.
So most of the answers here are about comparing Dictionary to Hashtable for general purposes, not why they chose that particular implementation.
In that particular implementation, you are correct, it is using object as the return type, so the strongly typed benefits of dictionary are not available.
IMO it boils down to New vs Old, ArrayList, Hashtable etc are the older tech, and are largely disfavored in general, because they do not have a host of features (described in the other answers). Although those features are not used in this particular case, there are no strong benefits for switching back to the old tech, and it provides a better example for personal development.
So its more just a matter of "this is the way we do it now"
The HashTable is weakly typed and can only return Object. The Dictionary<> is strongly typed for whatever type you are storing in it.
Related
I have some integrations (like Salesforce) that I would like to hide behind a product-agnostic wrapper (like a CrmService class instead of SalesforceService class).
It seems simple enough that I can just create a CrmService class and use the SalesforceService class as an implementation detail in the CrmService, however, there is one problem. The SalesforceService uses some exceptions and enums. It would be weird if my CrmService threw SalesforceExceptions or you were required to use Salesforce enums.
Any ideas how I can accomplish what I want cleanly?
EDIT: Currently for exceptions, I am catching the Salesforce one and throwing my own custom one. I'm not sure what I should do for the enums though. I guess I could map the Salesforce enums to my own provider-agnostic ones, but I'm looking for a general solution that might be cleaner than having to do this mapping. If that is my only option (to map them), then that is okay, just trying to get ideas.
The short answer is that you are on the right track, have a read through the Law of Demeter.
The fundamental notion is that a given object should assume as
little as possible about the structure or properties of anything else
(including its subcomponents), in accordance with the principle of
"information hiding".
The advantage of following the Law of Demeter is that the resulting
software tends to be more maintainable and adaptable. Since objects
are less dependent on the internal structure of other objects, object
containers can be changed without reworking their callers.
Although it may also result in having to write many wrapper
methods to propagate calls to components; in some cases, this can
add noticeable time and space overhead.
So you see you are following quite a good practise which I do generally follow myself, but it does take some effort.
And yes you will have to catch and throw your own exceptions and map enums, requests and responses, its a lot of upfront effort but if you ever have to change out Salesforce in a few years you will be regarded a hero.
As with all things software development, you need to way up the effort versus the benefit you will gain, if you think you are likely never to change out salesforce? then is it really needed? ... for you to decide.
To make use of good OOP practices, I would create a small interface ICrm with the basic members that all your CRM's have in common. This interface will include the typical methods like MakePayment(), GetPayments(), CheckOrder(), etc. Also create the Enums that you need like OrderStatus or ErrorType, for example.
Then create and implement your specific classes implementing the interface, e.g. class CrmSalesForce : ICrm. Here you can convert the specific details to this particular CRM (SalesForce in that case) to your common ICrm. Enums can be converted to string and the other way around if you have to (http://msdn.microsoft.com/en-us/library/kxydatf9(v=vs.110).aspx).
Then, as a last step, create your CrmService class and use in it Dependency Injection (http://msdn.microsoft.com/en-us/library/ff921152.aspx), that's it, pass a type of ICrm as a parameter in its constructor (or methods if you prefer to) . That way you keep your CrmService class quite cohesive and independent, so you create and use different Crm's without the need to change most of your code.
Is there any generic alternative / implementation for MemoryCache?
I know that a MemoryCache uses a Hashtable under the hood, so all it would take is to transition into using a Dictionary<,>, which is the generic version of a Hashtable.
This would provide type safety and provide performance benefits as no boxing/unboxing.
EDIT: Another thing I'm interested in is having a different key type. The default is a System.String.
Is there any generic alternative / implementation for MemoryCache?
Not in the base class library. You'd have to roll your own, though I, personally, would just make a wrapper around MemoryCache that provides the API you wish.
This would provide type safety and provide performance benefits as no boxing/unboxing
The type safety can be handled fairly easily in a wrapper class. The boxing/unboxing would only be an issue if you were storing value types (not classes), and even then, would likely be minimal, as it's unlikely that you're pushing and pulling from cache often enough to have this be a true performance issue.
As for type safety and usability, I've actually written my own methods to wrap the MemoryCache item's calls in a generic method, which allows a bit nicer usage from an API standpoint. This is very easy - typically just requires a method like:
public T GetItem<T>(string key) where T : class
{
return memoryCache[key] as T;
}
Similarly, you can make a method to set values the same way.
EDIT: Another thing I'm interested in is having a different key type. The default is a System.String.
This is not supported directly with MemoryCache, so it would require a fair bit of work to make your own key generation. One option would be to make a type safe wrapper which also provided a Func<T, string> to generate a string key based off your value - which would allow you to generate a cache entry for any type T. You'd have to be careful, of course, to include all data in the string that you wanted as part of your comparison, however.
I wrote mine, FWIW:
https://github.com/ysharplanguage/GenericMemoryCache#readme (link dead)
There is a fork of the original code here:
https://github.com/caesay/GenericMemoryCache
Just curious: sure, we all know that the general case of type inference for generics is undecidable. And so C# won't do any kind of sub-typing at all: if Foo<T> is generic, Foo<int> isn't a subtype of Foo<T>, or Foo<Object> or of anything else you might cook up. And sure, we all hack around this with ugly interface or abstract class definitions.
But... if you can't beat the general problem, why not just limit the solution to cases that are easy. For example, in my list above, it is OBVIOUS that Foo<int> is a subtype of Foo<T> and it would be trivial to check. Same for checking against Foo<Object>.
So is there some other deep horror that would creep forth from the abyss if they were to just say, aw shucks, we'll do what we can? Or is this just some sort of religious purity on the part of the language guys at Microsoft?
Update:
This is a very old thread. These days, C# has var, which solves half of what I complained about, and then using the Linq style of anonymous delegates, has a great notation for not needing to type in the same stuff twice. So every aspect of what I was objecting to has been resolved by more recent changes to C# (or perhaps it simply took me a while to learn about things that were just being introduced around when I posted the thread...) I use these new features now in the Isis2 system for reliable cloud computing (isis2.codeplex.com) and I think the library has a very clean look and feel as a result. Check it out and let me know what you think). -- Ken Birman (July 2014)
They already have solved it for many of the "easy" cases: C# 4.0 supports covariance and contravariance for generic type parameters in interfaces and delegates. But not classes unfortunately.
It's fairly easy to workaround this limitation:
List<Foo> foos = bars.Select(bar => (Foo)bar).ToList();
it is OBVIOUS that Foo<int> is a subtype of Foo<T>
To you maybe, but not to me.
To me, the huge hole this rips into the type system is simply not acceptable. If you want to throw type-safety out the window like that, I'd much rather use a dynamically typed language that was actually designed for this stuff.
The fact that arrays are covariant, even though this is known to break type-safety, is bad enough, now you want to break it for everything?
This goes to the very heart of what a type system is about. All a type system does is reject programs. And because of Rice's Theorem, those rejected program include perfectly well-typed, type-safe programs.
That is a huge cost. Taking away expressivity, preventing me from writing useful programs. In order to justify that cost, the type system better pay be back big time. It has basically two ways of doing that: giving back expressivity at the type-level it took away at the program-level and type-safety.
The former is out, simply because C#'s type system isn't powerful enough to let me express anything even remotely interesting. This leaves only the latter, and it is already on pretty shaky ground because of null, covariant arrays, unrestricted side-effects, unsafe and so on. By making generic types automatically covariant, you more or less completely take away the last shred of type-safety that is left.
There are only very few cases where S <: T ⇒ G<S> <: G<T> is actually type-safe. (IEnumerable is one such example.) And there are probably equally many cases where only S <: T ⇒ G<T> <: G<S> is type-safe. (IObservable, IComparer, IComparable, IEqualityComparer.) Generally, neither G<S> <: G<T> nor G<T> <: G<S> are type-safe.
The point is that you can't do it for all cases, so you don't do it for any. Where do you draw the line is the problem. If you don't do it for any than everyone who uses C# knows that it doesn't do that. If you do it part of the time, that is when it gets complicated. It can become a guessing game as to how your code will behave. It's all the edge cases on what is easy and what is not that become complex to the programmers and can cause errors in code.
Here is a scenario that would absolutely cause havoc. Let's say that you can infer boo is bar in scenario A. Someone else comes and changes part of the base type and this no longer holds true. By making it either always apply, or never apply, you don't run into this situation, ever. In a complex environment, tracking down a problem like this can be an absolute nightmare, especially when you factor in this may not be catchable during the compile time (reflection, the DLR etc.). It's so much easier to write code to manually handle the conversion up front, than assume that it will work in your scenario when the possibility that sometime down the line it just won't (not counting upgrading to a new version).
C# 4.0 does fix some of this as they allowed inference on what they felt is "safe" for the programmers.
A really good real life example of a language that is muddied and made more complex than necessary by special cases is English. In a programming language things like "i before e except after c" make the language harder to use and as such, less useful.
Since instances of generic classes have different method signatures I don't belive it would make any sence to consider specific classes to be inherited from base classes.
class Base<T>
{
public T Method() { return default(T);}
}
If you suggest that Base and Base than both of them have "Method" with the same signature (coming from base class) and it can be called by using reference to base class.
Can you please explain what obvious return value "Method" will have in your system if one points to Base<int> or Base<string> object by pointing to base class?
So, I found an elegant work-around for my real problem (although I do find that C# is overly constraining).
As you've gathered, my main goal is to write code that can register a callback to a method that you'll write later (in 2011, for example) and that was defined externally with generic type parameters that don't exist today, hence aren't available to me at the time I wrote my library (today).
For example I need to make a list of objects you'll define next year, and iterate over the elements of the list, calling back to each object's "Aggregate<KeyType, ValueType>" method. My frustration was that while you can certainly register your class, or an object in your class, C# type checking wasn't letting me call the methods because I don't know the types (I can get the types via GetType() but can't use those as types in expressions). So I was starting to use reflection to hand-compile the desired behavior, which is ugly and can violate type safety.
And the answer is... anonymous classes. Since an anonymous class is like a closure, I can define my callbacks inside the "register" routine (which has access to the types: you can pass them in when you register your objects). I'll create a little anonymous callback method, right inline, and save a delegate to it. The callback method can call your aggregator since C# considers it to "know" the parameter types. And yet my list can list methods with known type signatures at the time I compile my library, namely tomorrow.
Very clean and C# doesn't end up driving me insane. Still, C# really doesn't try hard enough to infer subtype relationships (sorry Eric: "what should be subtype relationship"). Generics aren't macros in C. Yet C# is much too close to treating them as if they were!
And that answers my own (real) question.
I need a generic collection class which I can add to, and enumerate over. Since ICollection<T> inherits from IEnumerable<T>, the class really just needs to inherit from ICollection<T>. Is there a simple generic class in the BCL that just inherits ICollection<T> like a generic version of CollectionBase? If not, then what class comes closest?
I would guess List<T> which is what I've been using but i don't need to sequential aspect. Is there anything better (by which I mean [smaller memory footprint/faster access/simpler])? Bag would be perfect if it existed.
EDIT 1: In my particular instance, I'm .concating to another IEnumerable, querying it, and then displaying the results (in no particular order). I'm not attempting to make my own class. I've just needed to make a throwaway collection so many times, that I thought it would be useful to find the best throwaway to use. Because I feel I've done something similar so many times, I felt I should keep this question as generic as possible (no pun intended), I know better now.
EDIT 2: Thanks for everybody's answers, As #BlueRaja pointed out, any simple class is going to have about the same overhead, and thus I think I will be sticking with my original ways of using List<T>. Since they are all about the same, my silly reasons of "It's easier to type", and "I don't have to bring in yet another using" aren't such bad reasons.
[smaller memory footprint/faster access/simpler]
They are all going to have pretty much the same memory footprint, and if you use ICollection the interface will not change.
What really matters is which will scale best for the operations you need: Linked-list does better appending/removal (of head/tail elements), while an array-based list has random-access. There are other structures too - which you should use depends on your application.
You'll probably want to look into Collection<T>. It was designed for the express purpose of subclassing, as the documentation indicates:
Provides the base class for a generic collection.
Having said that, any of the collections are fine; I've inherited from List<T>, Stack<T> and so on; pick whichever one is closest to the functionality you actually need.
Smaller and faster all depends on what exactly you're doing and what your needs are. The only other class I might recommend is LinkedList<> which implements ICollection<>.
You could use Reflector to check the .NET FCL and see what classes use that collection. (There is a search feature that can be started by F3.)
You can also take a look at the C5 Library to see if a collection has already been implemented that meets your needs. Check out page 13 of the C5 Manual for the collection interface hierarchy.
CollectionBase existed primarily to provide a simple mechanism to create typed collections. With Generics, all collections are now typed. The vast majority of cases where extensions of CollectionBase used to be used should now be using any of the built-in collections such as List<> or LinkedList<>.
Collection<> still exists for those that need to provide a custom collection for reasons other than type (i.e., extra validation on add, or some non-standard logic). Collection<> is not nearly as commonly used as CollectionBase was and serves a much smaller need.
The advantage of using generics is that it increases the type safety - you can only put in the correct type of thing, and you get out the correct type without requiring a cast. The only reason I can think of for not using generic collections is that you need to store some arbitrary data. Am I missing something? What other reasons are there to not use generics when dealing with collections?
If you need to store arbitrary data, use List<object> (or whatever). Then it's absolutely clear that it's deliberately arbitrary.
Other than that, I wouldn't use the non-generic collections for anything. I have used IEnumerable and IList when I've been converting an object reference and didn't know the type to cast it to at compile-time - so non-generic interfaces are useful sometimes... but not the non-generic classes themselves.
The obvious other reason is working with code (possibly legacy) that does not use generic collections.
You can see this happening in .NET itself. System.Windows.Form.Control.Controls is not generic, nor is System.Web.UI.Control.Controls.
Generics are almost always the right thing to use. Note that languages like Haskell and ML essentially only allow that model: there is no default "object" or "void*" in those languages at all.
The only reasons I might not use generics are:
When the appropriate type is simply not known at compile time. Things like deserializing objects, or instantiating objects through reflection.
When the users that will be using my code aren't familiar with them (yet). Not all engineers are comfortable using them, especially in some more advanced patterns like the CRTP.
The main advantage is the is no boxing or unboxing penalty with generic collections of value types. This can be seen if you examine the il using ildasm.exe. The generic containers give better performance for value types and a smaller performance improvement for reference types.
Type variance with generics can trip you up, but mostly you should use generic collections. There isn't a really a good reason to avoid them, and all the reason in the world to avoid un-typed collections like ArrayList.
Here's one answer: The change from Hashtable to Dictionary.
One thing I think you need to consider is that a generic collection is not always a drop in replacement for a non-generic collection. For example, Dictionary<object,object> can not simply be plugged in for an instance of Hashtable. They have very different behavior in a number of scenarios that can and will break programs. Switching between these two collections forces a good programmer to examine the use cases to ensure the differences do not bite them.
The non-generic Collection in the Microsoft.VisualBasic namespace has some annoying quirks and goofiness, and is in a lot of ways pretty horrible, but it also has a unique feature: it is the only collection which exhibits sensible semantics if it's modified during an enumeration; code which does something like delete all members of a Collection which meet a certain predicate may need to be significantly rewritten if some other collection type is used.