Reputation: 1422
I've searched just about everywhere and not even sure it's possible, but what the hey, I thought I would see what you C# wizards might have for a solution or workaround.
TL;DR:
I have a multi-dimensional collection using C# dictionaries and want to indicate what each string in the dictionary is for, something like this:
private Dictionary<string: Area, Dictionary<string: Controller, string: Action>> ActionCollection;
Which of-course does not work. For now I'm just commenting the dictionary.
Suggestions, thoughts, ideas?
Upvotes: 10
Views: 8376
Reputation: 22073
You cannot do that, but you could add a summary.
For example:
/// <summary>
/// Dictionary<Area, Dictionary<Controller, Action>>
/// </summary>
private Dictionary<string, Dictionary<string, string>> ActionCollection;
These comments will show up in the intellisense.
Or:
If you want to extract info with reflection, you could use custom attributes
If it is just for readability, you could create aliases for it:
using Area = System.String;
using Controller = System.String;
using Action = System.String;
namespace MyApp
{
public class MyClass
{
private Dictionary<Area, Dictionary<Controller, Action>> ActionCollection;
}
}
But intellisense will show string
@MMM says about invalid xml, you can do this:
/// <summary>
/// Dictionary<Area, Dictionary<Controller, Action>>
/// </summary>
Upvotes: 12
Reputation: 463
It's possible by using Tuple Field Names within List:
private List<(string Area, List<(string Controller, string Action)>)> ActionCollection;
That's feature from C# 7.0 or from .NET 4.3 by importing System.ValueTuple nuget.
Upvotes: 2
Reputation: 726699
Make a class that pairs the key or the value with the annotation:
class AnnotatedVal {
public string Val {get;}
public string Annotation {get;}
public AnnotatedVal(string val, string annotation) {
// Do null checking
Val = val;
Annotation = annotation;
}
public bool Equals(object obj) {
var other = obj as AnnotatedVal;
return other != null && other.Val == Val && other.Annotation == Annotation;
}
public int GetHashCode() {
return 31*Val.GetHashCode() + Annotation.GetHashCode();
}
}
private Dictionary<AnnotatedVal,Dictionary<AnnotatedVal,AnnotatedVal>> ActionCollection;
Now you can use AnnotatedVal
in your dictionaries to assure segregation:
ActionCollection.Add(new AnnotatedVal("hello", "Area"), someDictionary);
if (ActionCollection.ContainsKey(new AnnotatedVal("hello", "Area"))) {
Console.WriteLine("Yes");
} else {
Console.WriteLine("No");
}
if (ActionCollection.ContainsKey(new AnnotatedVal("hello", "Controller"))) {
Console.WriteLine("Yes");
} else {
Console.WriteLine("No");
}
The above should produce
Yes
No
because AnnotatedVal("hello", "Area")
and AnnotatedVal("hello", "Controller")
use different annotations.
Upvotes: 1
Reputation: 6948
You could wrap each string in it's own class. Then the declaration and intellisense will be descriptive:
public class Area
{
public string area { get; set; }
public override string ToString()
{
return area;
}
}
public class Controller
{
public string controller { get; set; }
public override string ToString()
{
return controller;
}
}
public class Action
{
public string action { get; set; }
public override string ToString()
{
return action;
}
}
private Dictionary<Area, Dictionary<Controller, Action>> ActionCollection;
Upvotes: 0