1

NOTE: this question is subtly different than the potential duplicate ... and this has answers that work - read both before voting please :) .

--

We have two dictionaries that have a common base type for the value:

Here is the Code:

// Three classes
class BaseClass {...}
class Foo : BaseClass {...}
class Bar : BaseClass {...}

// Two collections
var fooDict = new Dictionary<long, Foo>;
var barDict = new Dictionary<long, Bar>;

// One method
public void FooBar (Dictionary<long, BaseClass> dict) {...}

// These do not work
FooBar(fooDict);
FooBar(barDict);

Is there a way for inheritance to work in a dictionary, or do we have to use a different paradigm - or am I just being stupid?

Any help or guidance with this would be appreciated.

Thank you in advance.

Ruskin
  • 5,721
  • 4
  • 45
  • 62
  • So this is not enabled by design - because it would be unsafe to do so ... I'll look at wavy's answer below – Ruskin Oct 31 '14 at 10:03
  • Note to future readers - two good solutions below from WavyDavy and HimBromBreere - check them both out – Ruskin Oct 31 '14 at 10:44

2 Answers2

4

The trick is to make the method generic and restrict the type via the where keyword. Try this:

namespace GenericsTest
{
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();

        p.Run();

        Console.In.ReadLine();
    }

    private void Run()
    {
        Dictionary<long, Foo> a = new Dictionary<long, Foo> {
            { 1, new Foo { BaseData = "hello", Special1 = 1 } },
            { 2, new Foo { BaseData = "goodbye", Special1 = 2 } } };

        Test(a);
    }

    void Test<Y>(Dictionary<long, Y> data) where Y : BaseType
    {
        foreach (BaseType x in data.Values)
        {
            Console.Out.WriteLine(x.BaseData);
        }
    }
}

public class BaseType { public string BaseData { get; set; } }

public class Foo : BaseType { public int Special1 { get; set; } }

public class Bar : BaseType { public int Special1 { get; set; } }
}

Output:

hello
goodbye
wavydavy
  • 369
  • 3
  • 8
2
public void FooBar<T> (Dictionary<long, T> dict) where T : BaseClass {...}

EDIT: Another way would be to let Foo and Bar implement the same interface. Then you can do it without the generic-stuff:

interface IFoo {}
class Foo : IFoo {}
class Bar : Bar {}

public void FooBar(Dictionary<long, IFoo> dict) {...}
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111