VS 2008 Intellisense for C# static dictionaries - c#

I have the following in a C# class:
public static readonly SortedDictionary<string, string> Fields =
new SortedDictionary<string, string>
{ ... }
I was hoping there was a way to get Intellisense to provide prompts for all the keys defined in Fields. It supplies lists of the methods and properties in the class, including the Fields property, but when I go to access Fields[ or Fields[", it says nothing other than that I need to supply a string key. Is there a way to have it tell me a list of the string keys since this is a static class property that is not at all dynamic or changed after compilation?

If the keys are static wouldn't you be better off using an enumeration as your key instead of a string?
With an enumeration your compiler can tell you what the options are, but you can't do that with strings.

Do this instead:
public enum MyKeys
{
Key1,
Key2,
Key3
}
public static readonly SortedDictionary<MyKeys, string> Fields =
new SortedDictionary<MyKeys, string>
{ ... }
This will cause intellisense to pick up the enum type so you'll get the desired effect.

It seems to me that you assume that readonly there means that the dictionary won't ever change. This isn't the case - it only means that the value of the field (which is a reference to the dictionary) won't change (and even then it can still change while inside constructor, and can be null before it executes). The dictionary itself is quite mutable.

The best way for you to do this is probably to create public static readonly fields or properties.
If you need dictionary-like behavior, you should make the keys an enum as other people have suggested.
Remember that all of the dictionary class are mutable, which means that other code can add or remove items from your dictionary. The only way to prevent this would be to inherit a ReadOnlyCollection around a KeyedCollection and expose the indexer.

I have used static properties to do this.
What I have done for a Settings class of mine in order to get Intellisense was to create a code snippet that creates a static property. The code snippet is set up so that I enter the name of the setting and that same name is used in both the Property name and the lookup name.
Like this:
<Code Language="CSharp" Kind="method decl">
<![CDATA[ public static string $name$
{
get { return GetSetting("$name$", $default$); }
set { SaveSetting("$name$", value); }
}
]]>
</Code>
The GetSetting method would do something like this:
private static string GetSetting(string name)
{
if (!_Fields.ContainsKey(name))
_Fields.Add(name, default);
return _Fields[name];
}
This makes it really easy to add static properties and still get Intellisense.

Related

get method for a readonly member in C#

I have a class definition in which a readonly member is defined.
private readonly Dictionary<string, string> map = new Dictionary<string, string>();
Now in order to test my design, I want to access this member outside its class definition. I was thinking of providing a get method but unable to write an error free syntax.
Is it possible to assign value to a member(using new) and still able to define its get method?
PS: I am new to C# language.
EDIT:
I have not written the code, its just a statement I have copied from an already written module. I have made some design changes in the module and want to test it with minimal changes possible in the code, so for that I was looking to get the readonly access of this member outside the class.
You can define a read-only property for permitting public access to your field:
private readonly Dictionary<string, string> map =
new Dictionary<string, string>();
public Dictionary<string, string> Map
{
get { return map; }
}
Note that this will only prevent external classes from changing the instance reference assigned to map, not from changing the content of the dictionary itself.
One could argue that you shouldn't write tests for private members of a class. Tests should only use the public interface and don't rely on the internals of the class, since you should be able to refactor internals of the class without breaking any tests.
If you add a public getter 'only for testing' there's no guarantee that someone will start using somewhere in the project.
If you really want to expose the dictionary and use .NET 4.5, use ReadOnlyDictionary class to make sure that the caller won't change anything.
public IDictionary<string, string> Map
{
get { return new ReadOnlyDictionary<string, string>(map); }
}
Just create a simple getter
public Dictionary<string, string> Mapping
{
get { return map; }
}
You mean something like this?
readonly Dictionary<string, string> _map = new Dictionary<string, string>();
public Dictionary<string, string> Map
{
get { return _map; }
}
Why are you making this variable readonly?
If you're trying to give access to the values contained in the dictionary you could create a method that exposes the dictionary without allowing it to be modified:
public string GetMapValue(string key)
{
return _map[key];
}
You could write a public property function to return the private readonly map, e.g:
public Dictionary<string, string> Map { { get { return map; } } }
However, the Dictionary is still mutable. If you want a read-only Dictionary, see this SO question.

Dictionary uses object as key. The key is updated outside the dictionary

Consider a simple class:
public class TestClass<Val>
{
public Val Value{get;set;}
}
Create an instance of this class and define a dictionary where we use it as a key.
TestClass<int> TestCase = new TestClass<int>();
Dictionary<TestClass<int>, int> D = new Dictionary<TestClass<int>, int>();
Put 0 into the TestCase and add the entry to dictionary:
TestCase.Value=0
D.Add(TestCase,10)
Now the dictionary looks like this: {TestCase -> Value=0:10}
Now do this:
TestCase.Value=1
Now I have in the dictionary {TestCase -> Value=1 : 10} automatically, without putting the key 'TestCase -> Value=1' into the dictionary. How can I avoid it?
Basically, don't use mutable types as keys... or if you do, make sure you never mutate the key. The first would be preferable.
An even bigger problem is that if TestClass<Val> has a custom GetHashCode() / Equals() implementation, you can completely break the dictionary, as it may no longer be able to find a value for that key, even if you give it the exact instance you started with.
Anything you use as a key should ideally be immutable. For that reason, int and string make great choices, but you can also just make your type immutable, as per #lazyberezovsky's example.
Create immutable TestCase class:
public class TestClass<Val>
{
public TestClass(Val value)
{
Value = value;
}
public Val Value{ get; private set; }
}
Actually there is one single instance of TestClass. You created it outside dictionary and then added that instance to dictionary.
If you make changes to instance it reflects inside dictionary. This is shallow copying
To avoid this problem create a deepclone of your instance and then add in dictionary. In that case changes in one will not be reflected in another.

How to write a getter and setter for a Dictionary?

How do you define a getter and setter for complex data types such as a dictionary?
public Dictionary<string, string> Users
{
get
{
return m_Users;
}
set
{
m_Users = value;
}
}
This returns the entire dictionary? Can you write the setter to look and see if a specific key-value pair exists and then if it doesn't, add it. Else update the current key value pair? For the get, can you return a specific key-value pair instead of the whole dictionary?
Use an indexer property (MSDN):
public class YourClass
{
private readonly IDictionary<string, string> _yourDictionary = new Dictionary<string, string>();
public string this[string key]
{
// returns value if exists
get { return _yourDictionary[key]; }
// updates if exists, adds if doesn't exist
set { _yourDictionary[key] = value; }
}
}
Then use like:
var test = new YourClass();
test["Item1"] = "Value1";
It is not possible to do it in a way that would involve only properties. You theoretically could write a setter, but for a getter, you would need to specify a key that you want to retrieve. That is impossible since properties do not accept parameters. Natural way to accomplish what you want would be to use methods:
private Dictionary<string, string> users = new Dictionary<string, string>();
public void Set(string key, string value)
{
if (users.ContainsKey(key))
{
users[key] = value;
}
else
{
users.Add(key, value);
}
}
public string Get(string key)
{
string result = null;
if (users.ContainsKey(key))
{
result = users[key];
}
return result;
}
Alternatively, as others have already said, you could use indexers, but I've always found them a little cumbersome. But I guess it's just a matter of personal preference.
And just for the sake of completeness, this is how a setter could look like, although it's highly unusual and counter-intuitive to have such a property:
public KeyValuePair<string, string> Users
{
set
{
Set(value.Key, value.Value);
}
}
Internally, it uses the Set method from my previous snippet.
It looks like you want an "named indexer". Here's (my) one way to accomplish that using C#.
My approach exposes a property that returns an object (with a default indexer) which will perform the indexing into the appropriate field given the lambdas to do it.
There are reasons you may or not want to use this method, but I'll leave that to you. :)
You won't be able to do that with a property. You'll need to use methods for that, or add an indexer to your class. The get method can't accept a parameter (the key).
Another option, if you want someone to be able to easily add/remove keys to the dictionary but prevent them from setting an entirely new one would be to make the property a read-only property that returns a dictionary created in the constructor. It would be less flexible then adding get/set methods, but in common, simple cases it can do just fine.
It is possible to do so with the setter but highly unrecommended, and is completely impossible with the getter as it takes no parameter to determine what to get.
For the setter you would have to pass a Dictionary<string, string> with a single pair but it goes against what you would expect the getter/setter to usually do and completely stops you setting the entire Dictionary.
A much better way is to use a pair of methods which you can name Get and Set if you so desire.
Dictionary<string, string> param = new Dictionary<string, string>();
public void SetYourParameter(string parametrName, string paramValue)
{
param[parametrName] = paramValue;
}
public string GetYourParameter(string parametrName)
{
// ContainKey ---> It returns value if the key was found
if( param.ContainsKey(parametrName))
return param[parametrName];
else
return null;
}

Can pointers be used with Dictionary<TKey,TSource>?

Let's say I have the following class:
public class MyClass {
public string FirstAttribute {
get {
return Attributes["FirstAttribute"];
}
set {
Attributes["FirstAttribute"] = value;
}
}
public string SecondAttribute {
get {
return Attributes["SecondAttribute"];
}
set {
Attributes["SecondAttribute"] = value;
}
}
public Dictionary<string, string> Attributes;
public MyClass(Dictionary<string,string> att) {
Attributes = att;
}
}
and I wanted to be able to obtain a pointer to the value that is stored in the Dictionary, so that I can get and set the values (yes unsafe) directly without having to wait for the Dictionary to search for the element by key every time.
Is there a way to do that in c#?
No, I don't believe so. You could store a mutable wrapper in the dictionary though:
public class Wrapper<T>
{
public T Value { get; set; }
}
Then create the dictionary (which should be private, by the way - public fields are a really bad idea other than for constants) as a Dictionary<string, Wrapper<string>>. You can then keep fields for the Wrapper<string> objects associated with "FirstAttribute" and "SecondAttribute".
Frankly I don't think this would be a particularly good idea - I'd just stick with the dictionary lookup - but it's an option. (Assuming nothing's going to change which wrapper is associated with the keys.)
Another option is simply to use fields for the two specific attributes - when you're asked to set a new value, set it in the dictionary and set a field. When you're asked for the current value, just return the value from the field. Of course, that's assuming that you're in control of the dictionary (i.e. so it can't change outside your class).
No, no, no, no.
strings are immutable for a reason. A string might be shared between multiple references: modifying it directly with unsafe code might lead to weird behavior.
A way to go around this would be to write a wrapper class that olds your value, and keep a reference to an instance of that wrapper. The getters and setters would then modify the wrapper's property.
If the values in the dictionary were mutable, you could grab the reference to them and mutate them. But strings are immutable. So the dictionary has its own copy of a reference to your string, and you can't alter the string it is pointing to. If you try to replace it with another string, you need to update the dictionary with the new reference. So basically there's no way to improve on what you have in this situation.

C# non-evil fast array lookup?

I want to have a large number of class instances return the same similar fields of data, like in this example implementation:
foreach (SomeClass sc in SomeClasses)
{
System.Console.WriteLine(sc.GetData("1st field"));
System.Console.WriteLine(sc.GetData("Another field"));
System.Console.WriteLine(sc.GetData("and another"));
}
// ---- inside SomeClass:
Dictionary<string, string> myData;
public string GetData(string field)
{
return myData[field];
}
What I don't like is the string hashing, lookup and matching that has to happen over and over again in the example (I assume thats how Dictionary works). I would really like to find a better approach.
Coming from the C world, I thought of assigning all fields a unique integer key, such that I can change into an array lookup:
// ---- inside SomeClass:
string[] MyData;
public string GetData(int field_key)
{
return MyData[field_key];
}
Now the field lookup is efficient, but it just doesn't feel right in these "arrays are evil" times, and it is tedious and error prone to deal with the field_key integer.
I don't know if I'm chasing performance ghosts here, its just that I want to find a design that is both efficient and clean.
Suggestions?
Why don't you want a dictionary look-up? A very efficient implementation of a dictionary would be an index look up of the hash in an array. So the underlying implementation could boil down to the code in your second example. This would make it O(1)
Use the Dictionary
Because the fields are not known at compile time, but rather dynamic and user configurable, I'm going to modify your example program slightly to use an array of properties. Then I'd advocate an approach similar to yours but using your own custom class (here, called MyProperty) rather than string. Performance will be at least as good as (and maybe a tad better than) the string approach, but the benefit is that it gives you more flexibility: if you ultimately decide for performance reasons that you need to use an array or List approach, you can easily embed an array index into your MyProperty class. You'd have to change the implementation of GetData but not your calling code.
public static void Test1() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var properties=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var property in properties) {
Console.WriteLine(sc.GetData(property));
}
}
}
public class SomeClass {
public static readonly MyProperty FirstField=new MyProperty();
public static readonly MyProperty AnotherField=new MyProperty();
public static readonly MyProperty AndAnother=new MyProperty();
private readonly Dictionary<MyProperty, string> myData=new Dictionary<MyProperty, string>();
public string GetData(MyProperty property) {
return myData[property];
}
}
//default implementation of Equals and GetHashCode are fine here
public class MyProperty {}
HOWEVER, since your target application is really about collecting a set of dynamic and user configurable property getters, maybe you really want to make some Funcs? Code like the below will be very fast, and it still has the ability you want, namely it allows you to make a little dynamic, user-configurable list of property getters.
public static void Test2() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var getters=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var getter in getters) {
System.Console.WriteLine(getter(sc));
}
}
}
public class SomeClass {
public static readonly Func<SomeClass, string> FirstField=sc => sc.field0;
public static readonly Func<SomeClass, string> AnotherField=sc => sc.field1;
public static readonly Func<SomeClass, string> AndAnother=sc => sc.field2;
private string field0;
private string field1;
private string field2;
}
If your instances have the same fields, why not just use properties?
foreach (SomeClass sc in SomeClasses)
{
System.Console.WriteLine(sc.FirstField);
System.Console.WriteLine(sc.AnotherField);
System.Console.WriteLine(sc.AndAnother);
}
First, if you're not sure this actually is a performance problem for you, then yes, you are chasing performance ghosts and your current implementation is fine.
But if you found out during profiling that you really need to make this code faster, then your seems fine. “Arrays are evil” is mostly true only in public interfaces, it's fine to use them for implementation.
One thing I would change about your code though: create an enum containing the fields and use that instead of int. It's just as fast and much more readable. If the fields are not known at compile time, using int is fine. If you do know some of the fields at compile time, you could use static properties for them.

Categories