4

I am quite new to the C# world and I apologize if the Question title not exactly match the content. But now to my Problem:

I have the following construct:

    public interface IClass<TEnum>
    {
        Dictionary<TEnum, ISecondClass> dictionary { get; }
    }

    public abstract class ClassBase<TEnum> : IClass<TEnum>
    {
    public abstract Dictionary<TEnum, ISecondClass> dictionary { get; protected set; }
    }

    public class ConcreteClass : ClassBase<ConcreteClass.Concrete>
    {
        public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }

        public enum Concrete : ulong
        {

        }
    }

    public class OtherClass : ClassBase<OtherClass.Other>
    {
        public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }

        public enum Other : ulong
        {

        }
    }

My goal is to instantiate all existing concrete classes based on it's enums, store all instances in a dictionary and later invoke some methods on each object. I am not sure if this is even possible?

I am glad for any hint on this!

sra
  • 23,820
  • 7
  • 55
  • 89

3 Answers3

3

If I understand what you're trying to do, it sounds like a version of the Multiton Pattern. You may find it useful to research that.

From Wikipedia's example Multiton code:

class FooMultiton
{
    private static readonly Dictionary<object, FooMultiton> _instances = new Dictionary<object, FooMultiton>();

    private FooMultiton() {}

    public static FooMultiton GetInstance(object key)
    {
        lock (_instances)
        {   
            FooMultiton instance;
            if (!_instances.TryGetValue(key, out instance))
            {
                instance = new FooMultiton();
                _instances.Add(key, instance);
            }
        }
        return instance;
    }
}

This isn't directly pasteable into your class, but since you're looking for hints, I think it should point you in the right direction.

One word of caution about the above code: The method GetInstance will alter the dictionary if key isn't found. Personally, I associate the "Get" prefix with read-only methods. I'd either rename GetInstance or split it into two methods.

I'm not really sure what you mean by "instantiate all existing concrete classes based on it's enums", though. Can you clarify that?

Justin Morgan - On strike
  • 30,035
  • 12
  • 80
  • 104
  • Thanks for the fast reply, but that is not exactly my problem. I think I need to post more code to descripe all aspects of my problem. – sra Apr 21 '11 at 19:52
  • My Question and the title are not so well chosen so your answer is the closest one to what I am looking for. By the time I figured out how to invoke the methods by myself. – sra Apr 27 '11 at 05:53
1

Use Activator.CreateInstance() to create concrete classes' objects and store them into dictionary.

Pass your string classname from Enum and create dynamic class objects. Store them into Dictionary<Enum, ISecondClass>

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");

or

var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);

While retrieving, based on your enum key, you know what type of instance value represents.

Priyank
  • 10,503
  • 2
  • 27
  • 25
  • Yes, thats what I thought. But I want to use one loop to handle all and then I cant type the concrete baseclass coz all implementing another enum, based on the concrete class. I will try to repost some code, I see that what I've posted don't show all aspects of my problem. But I need to do this when I am not on my smartphone. Tomorrow I think. – sra Apr 21 '11 at 19:50
0

I don't understand a goal of the sample code, but you can write some thing like this:

public interface IClass
{
    void MethodToDynamicInvoke();
}

public abstract class ClassBase<T>
    : IClass
{
    private Dictionary<Type, List<IClass>> instances = new Dictionary<Type, List<IClass>>();

    public ClassBase()
    {
        List<IClass> list;
        if (!instances.TryGetValue(typeof(T), out list))
        {
            list = new List<IClass>();
            instances.Add(typeof(T), list);
        }

        list.Add(this);
    }

    public abstract void MethodToDynamicInvoke();

    public void InvokeMetodOnClassesWithSameEnum()
    {
        List<IClass> list;
        if (instances.TryGetValue(EnumType, out list))
        {
            foreach (var instance in list)
            {
                instance.MethodToDynamicInvoke();
            }
        }
    }
}

public class ConcreteClass
    : ClassBase<ConcreteClass.Concrete>
{
    public ConcreteClass()
        : base()
    {
    }

    public override void MethodToDynamicInvoke()
    {
        throw new NotImplementedException();
    }

    public enum Concrete : ulong
    {
    }
}

public class OtherClass : ClassBase<OtherClass.Other>
{
    public OtherClass()
        : base()
    {
    }

    public override void MethodToDynamicInvoke()
    {
        throw new NotImplementedException();
    }

    public enum Other : ulong
    {

    }
}
Viacheslav Smityukh
  • 5,652
  • 4
  • 24
  • 42