What is the best way to store a map of key object to a collection of value objects?
I could use
Dictionary<KeyType, Collection<ValueType>>
but that approach tends to involve a lot of housekeeping, and clutters up the code.
The Lookup type is almost the result I'm looking for, but it's immutable and has no constructor. I could create my own custom class, but it seems like it should exist in the framework somewhere.
That's about your best answer. It's pretty common to use Dictionary<KeyType, ICollection<ValueType>>. Using the var keyword to declare your local variables is the best way to tidy up.
Other than that, your only option is creating a MultiDictionary<T,K> type. You could also call it Lookup and put it in your own namespace?
Edit: Google says you should take a look at this for an existing implementation: Multi-value Dictionary C# source code (.NET 3.5). BSD2 license means you can use it for commercial apps with at attribution. :)
You could also, as for tidying, alias the specific generic type:
using MultiDictionary = Dictionary<string, ICollection<int>>;
Then later:
var foo = new MultiDictionary();
In .NET 3.5, there is ILookup<Tkey,TValue> and Lookup<TKey,TValue> that serves this purpose; however, the default implementation is immutable. I wrote a mutable variant for MiscUtil; EditableLookup<TKey,TValue> - which does exactly what you want.
Related
Before I switched to iOS development via Monotouch I played around a bit with ObjectiveC. Ever since one thing has been on my mind "Key Value Coding" (KVC). I have never understood what it is good for and what the magic behind it is.
For my understanding it is just a collections of names and values, like .NET's NameValueCollection: Instead of setting anObject.Address = "An address Value" you would write anObject.Properties["Address"] = "An address value".
Great. So what? Because this appears to be too easy to me I'm sure that can't be it.
Or is it because .NET has reflection and therefore has no need for something like Key-Value-Coding? I can grab the type of "anObject" and use reflection to loop all of its properties and look for the one called "Address" and then use reflection to set the value.
Is that maybe the analogy of KVC?
I'm hoping there is somebody out there who's a pro in ObjC and C#/.NET who can explain to me what the benefits are and how it would translate into .NET.
Please don't just point me to Apple's documentation. I know all that. I'm trying to find out if something has been missing in my coding-life so far by not knowing KVC? Or have I maybe been using something similar in .NET not being aware that it would translate into KVC if I was using ObjC?
From somebody who uses both every day for probably 3 years now:
As you figured out, there's nothing amazingly complex in KVC that can't be done with dictionaries and NameValueCollections in C#.
The big difference is that KVC is built in the language. An object in Obj-C IS a NameValueCollection. You don't have to change the way you develop (from classes and properties to dictionaries) to use it. You can create your object with the properties you want, and then later on call a valueForKey:#"name", and everything still works.
Now you can say: "yeah cool, but I can do that with reflection!". Sure you can, but just as before, you'll have to change the way you develop again, not counting the fact that reflection is a lot slower in general.
Another cool feature of KVC it it allows you to use KVO, which basically allows you to register to receive notifications about changes in any object without having to write a single line of code in those objects. So, in any object in your application, you can call "addObserver:forKeyPath:", and receive a callback if anybody else in your application changes that property. This is really useful for live apps, like iOS apps.
Again, you can implement KVO in C# (MVVM frameworks for example do this all the time), but you have to write extra code for that. In Obj-C, it's built in the language.
I blogged about this in the context of MonoMac, the peer project to MonoTouch but used for building Mac applications:
http://tirania.org/monomac/archive/2010/Dec-07.html
Key-Value Coding is a set of practices that allow applications to access object properties using strings. This is similar to Binding Expressions in Silverlight. In both cases the purpose is to allow tooling that does not directly have access to your native code to access properties from your program.
In particular, this is useful because some APIs can take advantage of this. For example CoreAnimation can animate properties given their "path" to the object. For example, you can do:
var animateX = CAKeyFrameAnimation.FromKeyPath ("position.x");
pos.Values = new NSNumber [] { 0, 10, 60 };
layer.AddAnimation (animateX, "move");
The "position.x" in this case references the layer's position, and within that position it's X component.
The blog post above goes into more detail about how you can actually expose your own objects to participate in this protocol (registering your own properties to make them visible to the Key-Value-Coding system).
Kenneth, another one of the MonoMac developers blogged about this extensively here:
http://cocoa-mono.org/archives/153/kvc-kvo-and-cocoa-bindings-oh-my-part-1/
In particular he deals with the similarities with Reflection and he shows you how to use [Export] to turn your C# code into KVC compliant code as well.
If you access a property like this
anObject.Address = "An address Value"
The code will be very "static". It will always access Address
You can create a more dynamic code like this
void SetProperty (string propertyName, string value)
{
anObject.Properties[propertyName] = value;
}
You would do this if you do not know at compile time which property will be accessed.
In c# you would typically use a Dictionary<TKey,TValue> for storing key/value pairs. Automatically accessing properties via KVC as in Objective-C is not supported in c#. You would either declare the property as
public Dictionary<string,string> Properties { get; private set; }
and instantiate it in the class constructor with
Properties = new Dictionary<string,string>();
then you could access it like this
anObject.Properties[propertyName] = value;
Or you would have to use Reflection to access the property
Type type = anObject.GetType();
// Or Type type = typeof(TypeOfAnObject);
PropertyInfo prop = type.GetProperty(propertyName);
prop.SetValue(anObject, propertyValue, null);
However, this is not very efficient.
In order to protect ourself from failure because of any renaming of properties (Let's say you regenerate your poco classes because you have changed some column names in the relevant Db table) is it a good practice to decalre constant strings that keep the property names inside?
public const string StudentCountPropertyName = "StudentCount";
public int StudentCount {get;set;}
For example: Think about a DataBinding; where you type the property name in the DataFieldName attribute explicitly.
Or this is not a good idea and there is a better and still safer way?
It is always a good idea IMHO to move any 'magic strings' to constants.
You could consider using lambda expressions to 'pick' your properties, for example:
GetDataFieldName(studentCollection => studentCollection.Count)
You will have to implement GetDataFieldName yourself, using a bit of reflection. You can look at HtmlHelperExtensions from MVC to see how it can be done. This will be the most safe approach, which gives you compile-time errors when something goes wrong and allows easy property renaming using existing refactoring tools.
From one point of view: if you using this property name multiple times it is good practice. It will help for sure with the refactoring and when you for example change property name you see that you need change this const also.
From another point of view i guess it will be ugly when my class with 10 properties will have 10 additional consts. Another solution if you want avoid consts or explicit name typing can be getting property names through the reflection.
Use such approach or not you should decide yourself.
I think it's a common practice to put this "magical string" or "magical numbers" in some kind of strong typed store.
Something you can consider is to code it in a Aspect Orientied Way.
For example the calls to notifypropertychagned can be realized with an attribute implemented with an aop framework, like PostSharp .
[NotifyChange]
public int Value {get;private set}
This tools also have some downsides but i think there are scenarios where they can save you a lot of work
I do not know if I fully understand your question, but if I understand it right I would have used an attribute for that, an example could be the use of ColumnAttribute in Linq which you use to map a property to a specific column in a database (http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.columnattribute.dbtype.aspx), like in this example:
[Column(Storage="ProductID", DbType="VarChar(150)", CanBeNull=False)]
public string Id { get; set; }
And I would never use DataFieldName, I would DataBind to the strongly typed objects (and of course also make an interface to the class that uses the property above so I easily can change the implementation in the future ;))
I suppose if the names are used in many places then it would be easier just to change them in this one place and use the constant as described in your comment.
However, a change to a database column name and object property name implies a change to your conceptual data model. How often do you think this is going to happen? In the early stages of a project, whilst conceptual modelling and implementation are paralellised across a dev team, this may be quite fluid, but once the initial conceptual modelling is done (whether this in a formalised conscious manner or just organically), it's usually quite unlikely that fundamental things like these are going to change. For this reason I think it's relatively unusual to have do this and the technique will only be productive in edge cases.
Absolutely. It's a good idea.
By the way, I would argue that these kind of things could be better stored in application settings, because you can define such things in an application configuration file later by overriding these settings.
Doing that this way you'll avoid re-compiling if some database, POCO or whatever changes, and as in newer Visual Studio versions like 2010, you can tell it to generate settings with "public" accessibility, you can share strongly-typed settings with any assembly that reference the one containing them.
At the end of the day, I'd change your code with DataBindingSettings.StudentCountPropertyName instead of a constant.
Easy to manage, more re-usable, and readable, as "you configure a data-binding with its settings".
Check this MSDN article to learn more about application settings:
http://msdn.microsoft.com/en-us/library/a65txexh(v=VS.100).aspx
I have a record type like this:
type Rule = {extension: string seq; subdir: string}
let rules : Rule list = // ...
And I want to bind it's instance to DataGridView. All my UI logic is implemented with C#. What is the best way to do this? Just make a reference to FSharp.Core in my C# project and bind? Or to make some simple record like this
type SimpleRule = {extension: string; subdir: string}
and a function that converts Rule list to a SimpleRule seq, which is represented as IEnumerable in C#.
The second way seems to be the best because I don't need to make a reference to FSharp.Core and I will work with IEnumerable, but there is too much conversion code and I am having problems with writing it. Maybe there is a better way to solve the problem?
I ended up using mutable record. Also I've created some wrapper-class for my library, which have several methods to add/delete rules and apply them, so I don't use any of F# classes such as FSharpList in C#.
I'd like to implement MVC while using LINQ (specifically, LINQ-to-entities). The way I would do this is have the Controller generate (or call something which generates) the result-set using LINQ, then return that to the View to display the data. The problem is, if I do:
return (from o in myTable select o);
All the columns are read from the database, even the ones (potentially dozens) I don't want. And - more importantly - I can't do something like this:
return (from o in myTable select new { o.column });
because there is no way to make anonymous types type-safe! I know for sure there is no nice, clean way of doing this in 3.5 (this is not clean...), but what about 4.0? Is there anything planned, or even proposed? Without something like duck-typing-for-LINQ, or type-safe anonymous return values (it seems to me the compiler should certainly be capable of that), it appears to be nearly impossible to cleanly separate the Controller from the View.
Use a view model layer. Your view has to know what it is going to display. I guess its possible to create a view that just formats a multi-dimensional array of data, but that isn't exactly the best reason to go with an MVC solution. You can however populate a view model with an anonymous object for consumption in your view.
Anonymous types are primarily designed to be used within a method. They are not suitable for communication between methods.
If you need to pass a set of data between two functions the best way is to create a new type wrapping the data or use a loser grouping like Tuple<T1,T2> or KeyValuePair<TKey,TValue>
How about this?
I assume that you have an entity class for your table 'myTable' (let's call it 'MyTableEntity'), so why don't you instantiate a new MyTableEntity object and use object initializer to fill only those columns you want?
return (from o in myTable select new MyTableEntity { AColumn = o.column });
This will not translate to a SELECT * as you asked, but you'll still have a way to pass a strongly-typed object to a view.
You have to be careful to just make use of the initialized properties inside the view and that's it.
Does this makes sense for you?
Since no one even attempted to answer my question, I will answer it myself..
It turns out, C# 4.0 supports duck-typing - they call it dynamic typing. However, in using dynamic types to return anonymous types, we lose the benefits of strong types:
Compile-time type-checking
Performance
Intellisense
I've opened a feature request to have strongly-typed anonymous return types here - if you think this would be a useful addition to C# 5, follow the link and let the .Net team know!
On .NET 4.0 Anonymous types can easily be converted to ExpandoObjects and thus all the problems is fixed with the overhead of the conversion itself.
Check out here
You can easily convert anonymous types into dynamic objects, here is the simple implementation of Donymous objects (Dynamic anonymous objects) that can populate from Anonymous object or DataReader.
Currently, I've created a class with ~30 properties to be set. This is done to build up a URL request later on(ie, "http://www.domain.com/test.htm?var1=a&var2=b...&var30=dd").
The issue I'm facing is the property names don't necessarily match the query variable names(this is intended to be different). For example, I may have a variable titled "BillAddress", whereas the query variable will need to be "as_billaddress".
I have no control over the query variable naming scheme as these are set at an external source.
One possible solution I've used is creating a custom attribute and decorating the properties with their respective query counterparts:
[CustomQueryAttribute("as_billaddress")]
string BillAddress{get;set;}
To retrieve the attribute though, requires a little reflection and due to the larger number of properties, I was curious if there is a neater way to accomplish this functionality. Not so much as setting/retrieving custom attributes without reflection, but being able to tie an alternate string variable to any property.
I've also pondered about setting each variable up as a sort of KeyValuePair, with each key representing the query counterpart, but I didn't get too far in that thought.
To summarize/clarify my above backstory, what would you do to associate a string with a property(not the value of the property)?
As always, any comments are greatly appreciated.
I would probably stick with a custom attribute, but the other potential option would be to do something like hold a static Dictionary that had string and property info (or property name), so you could get/set the property directly via this.
Something like:
static Dictionary<string, PropertyInfo> propertyMap = new Dictionary<string, PropertyInfo>();
static MyClass()
{
Type myClass = typeof(MyClass);
// For each property you want to support:
propertyMap.Add("as_billaddress", MyClass.GetProperty("BillAddress"));
// ...
}
You could then just do a dictionary lookup instead of using reflection in each call... This could also be setup fairly easy using configuration, so you could reconfigure the mappings at runtime.
A custom attribute seems like the best option to me - the framework seems to do this a lot as well (specifically with serialization).
If you look at popular ORM mappers then nearly all either use custom attributes or some kind of XML mapping file. The advantage of the latter is that you can modify the mapping without recompiling your application - the downside is that it hurts performance. However, I'd say your choice seems perfectly reasonable.