VansFannel
VansFannel

Reputation: 45921

Dictionary without generics

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

Answers (3)

adjan
adjan

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

ironstone13
ironstone13

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Related Questions