I came across this class while reading a C# book and have some questions.
Why is this added into System.Linq namespace and not into usuall Collections namespace?
What the intention behind this class is
Why this class is not intended for direct instantiation? This is available through the ToLookup extension only, right?
Purpose of the class: a dictionary where a key can map to multiple values. Think of it as being for grouping rather than one-to-one mapping.
Only through ToLookup decision: Pass. Again, seems like a bad call to me. On the other hand, it means that the result is immutable to the outside world, which is quite nice. It's quite easy to write your own collection which supports this, of course - but it would be have been quite nice to have it in the collections "properly". My guess is that MS didn't have the time/money to go through the pretty rigorous design/test required to make it a first class collections decision.
Namespace decision: Probably related to the above. Having a version in System.Collections.Generic which you couldn't create yourself would have been a bit odd.
As an aside, note that MiscUtil also includes a MiscUtil.Linq.EditableLookup<,> class, that is similar; it implements the regular ILookup<,> interface, but is fully mutable - so you can create it and add your own values.
Related
What is the real reason for that limitation? Is it just work that had to be done? Is it conceptually hard? Is it impossible?
Sure, one couldn't use the type parameters in fields, because they are allways read-write. But that can't be the answer, can it?
The reason for this question is that I'm writing an article on variance support in C# 4, and I feel that I should explain why it is restricted to delegates and interfaces. Just to inverse the onus of proof.
Update:
Eric asked about an example.
What about this (don't know if that makes sense, yet :-))
public class Lookup<out T> where T : Animal {
public T Find(string name) {
Animal a = _cache.FindAnimalByName(name);
return a as T;
}
}
var findReptiles = new Lookup<Reptile>();
Lookup<Animal> findAnimals = findReptiles;
The reason for having that in one class could be the cache that is held in the class itself. And please don't name your different type pets the same!
BTW, this brings me to optional type parameters in C# 5.0 :-)
Update 2: I'm not claiming the CLR and C# should allow this. Just trying to understand what led to that it doesnt.
First off, as Tomas says, it is not supported in the CLR.
Second, how would that work? Suppose you have
class C<out T>
{ ... how are you planning on using T in here? ... }
T can only be used in output positions. As you note, the class cannot have any field of type T because the field could be written to. The class cannot have any methods that take a T, because those are logically writes. Suppose you had this feature -- how would you take advantage of it?
This would be useful for immutable classes if we could, say, make it legal to have a readonly field of type T; that way we'd massively cut down on the likelihood that it be improperly written to. But it's quite difficult to come up with other scenarios that permit variance in a typesafe manner.
If you have such a scenario, I'd love to see it. That would be points towards someday getting this implemented in the CLR.
UPDATE: See
Why isn't there generic variance for classes in C# 4.0?
for more on this question.
As far as I know, this feature isn't supported by CLR, so adding this would require significant work on the CLR side as well. I believe that co- and contra-variance for interfaces and delegates was actually supported on CLR before the version 4.0, so this was a relatively straightforward extension to implement.
(Supporting this feature for classes would be definitely useful, though!)
If they were permitted, useful 100% type-safe (no internal typecasts) classes or structures could be defined which were covariant with regard to their type T, if their constructor accepted one or more T's or T supplier's. Useful, 100%-type-safe classes or structures could be defined which were contravariant with respect to T if their constructors accepted one or more T consumers. I'm not sure there's much advantage of a class over an interface, beyond the ability to use "new" rather than using a static factory method (most likely from a class whose name is similar to that of the interface), but I can certainly see usage cases for having immutable structures support covariance.
These types of methods have always bothered me. Without digging through the code, I have no idea what the key or sub-value is supposed to be in this dictionary. I've done this myself about a thousand times, I'm sure. But it has always bothered me because it lacks so much information.
IDictionary<int,HashSet<int>> GetExportedCharges()
{
...
}
void GetVisitStatuses(IDictionary<int,HashSet<int>> exportedCharges)
{
...
}
Having the material in a dictionary makes sense, but all of the IDictionary methods have very abstract parameters. I suppose I could create a new class, implement IDictionary, and rename all of the parameters. It just seems like overkill. Makes be wish c# had a 'typdef' directive.
How do you avoid returning dictionaries like this? Or do you avoid this at all?
There is a very simple solution that you might find adequate:
public class IdToSetOfWidgetNumbersMap : Dictionary<int,HashSet<int>> { }
Advantages:
Seeing a method returning an IdToSetOfWidgetNumbersMap doesn't leave many questions open
The class can be left totally empty, or you can choose to provide aliases for the members exposed by Dictionary if you prefer
Disadvantage:
You need to create a do-nothing class for each type of dictionary
Personally I don't avoid returning dictionaries.
I agree, having only method signature it all looks very vague. So my rule is to ALWAYS write comments in a style "Dictionary (logical description of the keys) - (logical description of values)". And to hope that I will not need to use something horrible like
Dictionary<SomeType, <Dictionary<...>>
Before you start pointing me to duplicates just know that I have read nearly all the posts on SO about extension methods. I am just trying to play devil's advocate for a minute to consider the alternative to my working opinion.
Recently I was working on a project and a need came up for a method to be a base of an interface. So I suggested we write an extension method and it was shot down. Saying it added complexity and harder to debug.
I of course argued and got on SO to find all the wonderful posts that show the many reasons why to use extension methods. Not to forget that a lot of the .net framework uses them. We eventually did not use it as I was overruled by the team.
But then it got me thinking, are there times when an extension method could be used but shouldn't be?
I really couldn't think of any but thought I would post here and see if anyone could think of any other reasons why they shouldn't be used.
Any time you have a function which is "generally applicable" to an object of a certain type, regardless of its state, an extension method is a good choice.
For example, today I added two new extension methods to our codebase:
public static XElement ToXElement(this XmlElement element) { }
public static XmlElement ToXmlElement(this XElement element) { }
Both of these are, generally speaking, valid on the types they extend regardless of the state of the instance or where we are using it.
If your method does not meet that criteria, it should probably be moved to a helper method closer to the context where the particular case is always true or easily checked.
For example, a developer recently nominated this to be an extension method:
public static bool ParseYesNoBool(this string input) { }
There are two problems here: first, this will appear on all strings in the application, even though the number of strings which might ever be candidates for this case are very small. So we've broken the first rule, in that it is not useful regardless of state. Similarly, but second, the consumer of this functionality is limited to a single parser for one particular connector to an external system. So promoting implementation-specific functionality into the general-use namespace makes no sense. This was downgraded to a helper method in the parser.
As far as readability and debugging, that is just incorrect for a developer of any reasonable skill level.
In general if you control the source-code for the assembly and adding the method does not cause any breaking changes to existing code (which would have been the case if for example LINQ had not been implemented via extension methods) it is better to just add a normal method.
This discussion of the Framework Design Guildelines section on extension methods contains some good advice. I think the relevant portion for your scenario is:
To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface.
If your proposed usage did not pass that test then it should have been shot down.
I would say you should avoid them when "they do not make the intend of the code more clear". Of course, whether or not some code (or codeing style) is "more clear" varying widely between people, so that's pretty much useless. (I had one boss who said we shoudl avoid using interfaces because they made the code "too complex and hard to understand")
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
Any time you break the intent and design for the feature I would recommend reconsidering the use of an extension method. I see a few situations when you don't want to use an Extension method:
1) Changing the Object Model to allow for an Extension method: The class you want to create an extension on is an abstract class. This is going to require you either make each inherited class it's own version of the extension or remove abstract from the class. Either way, you are changing the object model in order to use an extension method.
2) Forgetting the Decorator Pattern: The number of extension methods you create for a class exceeds three. I find it is easier to organize/communicate and maintain the domain/object model with decorated objects than with extended objects. However, the opposite is also true: If a decorated object has less than four methods, I find a lot of almost "empty" objects in my project.
3) Private functions: Private functions are meant to modify(create, delete, etc..) the object and extension methods are meant to use the type, much like a struct would. If you find the extension is being assigned to another instance of the type then it probably should not be in an extension.
I don't understand, why use dynamic MethodBags when I can use ExpandoObject? What am I missing here?
MethodBags and analogous implementations tend to have some limitations. It may be easier just to implement your own class if you find yourself running into these roadblocks. Specifically:
Hard to implement state in a method bag. (Expression trees cannot contain objects that are statically typed as dynamic; no good syntax to create methods that rely on internal state on the same dynamic object.)
Can only add public methods. No virtual, private, protected, or abstract methods.
Can't implement an interface.
In comparison, ExpandoObjects are true classes and are much richer and more full-featured. They more closely mimic what you'd otherwise get for free in, say, Ruby or Python.
Quick note: for those who don't know, dynamic method bag is a technique for adding methods dynamically to an object. Bill Wagner describes it here with source code here.
The simple answer is that the MethodBag concept is just showing you a technique. You can absolutely use the ExpandoObject to do this, but there may be a time when you want to write your own class that inherits from System.Dynamic.DynamicObject. An example of this might be to provide a dynamic JSON, YAML, or XML object that lets you reference your data in dot-properties-notation rather than in the traditional stringy ways. If you inherit from DynamicObject, you may find that you want to allow the addition of dynamic functions to your class too. The MethodBag technique shows you how to do that. The ExpandoObject is just one example of a class that implements this technique. ExpandoObject will be good for 95% of what you need, and the MethodBag technique shows you how to custom write your own when you decide to do that for the last 5%.
I'm currently doing some refactoring (+ adding new features) to some of our framework classes. The situation is that we have a single (god-like) class which does a bunch of logic we'd like to split up. The class represents something like a validation rule for fiscal codes. So it does validation of the names of the person, birthdate etc..
What I am going to do is to split it up in single rules, basically a rule which validates the person's firstname against the fiscal code, another one for the birthdate and so on. For the programmer at the end it looks nearly the same. Instead of invoking the huge constructor of the FiscalCode rule, he'll do something like FiscalCode.GetRules(...) and pass the parameters here. The GetRules(...) will then internally construct the single rules and pass them back as an array. That's perfectly fine and correct for us.
So much for your background. Now my question is the following. The FiscalCode class (which is our current mighty god-class) has a lot of utility methods which will be needed by more of the single "rule classes" I'm going to create. What I know is that I will somehow still need the FiscalCode class, for doing the GetRules(...) thing (this is to remain constant somehow for the programmers, not that they have to do a completely new thing).
I have two options which come to my mind:
Create my new rule classes and access the public static utility methods of the FiscalCode class
Create my new rule classes as inner nested classes of the FiscalCode class s.t. I have already access the utility methods (and therefore no need for exposing my utility methods)
I have already a favorite, but I'd like to hear the opinion of some of you first.
Thx
As your methods became 'utility methods' you need to make them static and public, but probably you need to rename your FiscalCode to FiscalCodeUtil. So it will be obvious what kind of methods it contains.
I would also suggest a review of the Specification Pattern, which gives some direction on how to approach this type of problem. This post also gives some examples in C#.
The suggested Specification Pattern would steer you towards your option #1.
What dependencies do these utility methods have on the FiscalCode class or the rule classes? Is there state kept by them?
If there aren't any dependencies I'd suggest moving those utility methods to a seperate class, and have the FiscalCode class or rule class call into those methods as appropriate.
For the options you give, the only difference between 1) and 2) is whether the rule classes are visible to classes that don't use them. I don't think thats really an important objective. I used to worry about that all the time when I did c++... it was a waste of time.
IMO you should go for the first option because that way, you can expose the newly created classes to outside world, and can write code that is reusable elsewhere as well. If you go with the second option, you are creating very specialized classes. Your outside code may not even know of its existence, but that might be good for encasulation. Still, at some point you may decide to use the specialized rules outside the scope of your larger class, and for that scenario, you are better served with the first option. What is your pick though?
If the class will not be used outside the FiscalCode class, then make it nested. The important thing is to pull the responsibility of this new class out of FiscalCode; where it resides then becomes a mere question of choice. When the new class gets more dependents, you could make it an outer class.
I would go with it like this (I'm not that good at OOP so take it with a grain of salt):
Rule classes (nested in FiscalCode) implement an IRule interface exposing rule methods (like Validate(), with whatever return type floats your boat). FiscalCode
has an AddRule() method which manages an internal collection of rules and returns a reference to self in order to permit method chaining:
FiscalCode fc = new FiscalCode();
fc.AddRule(new RuleClass1(<params specific to RuleClass1>)
.AddRule(new RuleClass2(<params specific to RuleClass2>)
...
Also, FiscalCode has a Validate() method which iterates through each rule's Validate() and manages errors.
IMO this is quite handy to use and still permits to nested rule classes access FiscalCode's utility methods.