Reputation: 45921
I'm learning C# and I have an exercise with these three classes:
public abstract BaseClass<T> Where T : BaseClass<T>
public class Class1
public class Class2 : BaseClass<Class2>
On the exercise there is this:
var dictionary = new Dictionary { [class1] = class1, [class2] = class2 };
I think that here, Dictionary
is a shortcut for Dictionary<object, object>
; so I have added this class to the project:
public class Dictionary : Dictionary<object, object>
My problem here is that I'm not sure if I have declared correctly Dictionary
. Now the exercise works perfectly but maybe there is another option to declare Dictionary
. By the way, I have used dynamic
instead of object
and it also works.
My question is:
In the exercise, is Dictionary
a custom class or is another class from .NET Framework or whatever that I don't know?
Upvotes: 2
Views: 1025
Reputation: 13652
The line
var dictionary = new Dictionary { [class1] = class1, [class2] = class2 };
uses an object initializer to initialize the indexer of the Dictionary
class. This syntax is supported from C# Version 6 (see C# 6.0 Language Specification under section §7.6.11.2 Object initializers).
As you correctly found out, one way to get a class that allows such an behavoir is to derive a class from Dictionary<T,K>
. Another way is to write a Dictionary
class that uses an indexer. The simplest class that exhibits such a behavior is:
public class Dictionary
{
public object this[object index] {
get {return null;}
set {}
}
}
static void Main()
{
Class1 class1 = new Class1();
Class2 class2 = new Class2();
var dictionary = new Dictionary
{
[class1] = class1,
[class2] = class2
};
}
Which does not do anything, obviously, but it shows where the initialization syntax comes from.
Upvotes: 0
Reputation: 3443
In .NET Dictionary class is generic, and there is no other class named Dictionary
in BCL.
You can get a similar functionality form the predescessor - HashTable that also implements IDictionary interface
Note, that there is no need to inherit from Dictionary - just use the instance of generic class with the types you need, or use a Hashtable.
If you are in doubt if a specific class is in the BCL or not - check it's namespace.
If you are curious about it's implementation check reference source
Specifically for your exersise, it looks like you have to inherit from Dictionary and use a collection initializer:
Note: Don't inherit from Dictionary in production code, most of the times it is unnecessary.
namespace ClassLibrary2
{
public class TestClass
{
public abstract class BaseClass<T> where T : BaseClass<T> {}
public class Class1 { }
public class Class2 : BaseClass<Class2> { }
private class Dictionary : Dictionary<Class1, Class2> { }
public void Test()
{
var dictionary = new Dictionary { { new Class1(), new Class2() } };
}
}
}
By the way, having this public abstract class BaseClass<T> where T : BaseClass<T> {}
is an example of curiously recurring template pattern, @Eric Lippert wrote a nice article on that - see Curiouser and curiouser
Upvotes: 1
Reputation: 726599
The syntax from the exercise is invalid:
var dictionary = new Dictionary {
[class1] = class1
, [class2] = class2
};
This looks like a C# 6 dictionary initializer, which expects type parameters of the dictionary to be specified explicitly:
var dictionary = new Dictionary<object,object> {
[class1] = class1
, [class2] = class2
};
You do not need to create your own class derived from Dictionary<TKey,TVal>
, or use dynamic
.
Note: Using object
for both key and value type is required because your dictionary example uses classes Class1
and Class2
as both keys and values, while the classes have no common ancestor other than object
.
Edit:
I can't modify the exercise. So, I need to do something to make it compile
Your solution that derives Dictionary
from Dictionary<object,object>
is fine then. You can also write your own Dictionary
class that takes a dictionary-like initializer, but that would be a much harder exercise.
Upvotes: 1