mohammad
mohammad

Reputation: 1318

Find a class that it has a specific property value

Consider I have these classes

class BaseClass
{
    public int Variable {get; set;}
}
class Class1:BaseClass
{
    public Class1()
    {
        Variable=1;
    }
}
class Class2:BaseClass
{
    public Class2()
    {
        Variable=2;
    }
}

In another place I want to do this:

public BaseClass MyMethod(int i)
{
    //I want if i is 1 this method returns Class1
    //And if i is 2 this method returns Class2.
}

A solution is using switch statement. But my namespace has a lot of class and using switch results a lot of code lines.

Upvotes: 0

Views: 53

Answers (2)

csharpfolk
csharpfolk

Reputation: 4290

Your comment "But my namespace has a lot of class and using switch results a lot of code lines." tells me that you are doing something wrong.

This is classic problem, easily solved by factory pattern, using switch would be the best solution here:

switch(num) {
  case 1: return new Class1();
  case 2: return new Class2();
  default: throw new ArgumentException();
}

Maybe you should split your namespace?

Other solution with is a bit ugly because you will lose compile time checking, is to use Activator:

return (BaseClass)Activator.CreateInstance("AssemblyName", "Class" + num)

Based on comment, 100 classes and must select one.

public static class AmazingFactory {
    private static IDictionary<int, Type> _num2Type;

    private static void InitializeFactory() {
        var type = typeof(BaseClass);

        // get all subclasses of BaseClass 
        var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => type.IsAssignableFrom(p));

        foreach(var type in types) {
            int numberAtTheEnd = int.Parse(Regex.Match(type.Name, @"\d+$").Value);
            _num2Type[numberAtTheEnd] = type;
        }

    }

    public static BaseClass Create(int num) {
        if (_num2Type == null)
            InitializeFactory();

        return (BaseClass)Activator.CreateInstance(_num2Type[num]);
    }
}

Upvotes: 2

Oleg Golovkov
Oleg Golovkov

Reputation: 706

Looks like you don't want to return a class, but rather an instance of a class. The next question is where do you want to get your object from? If they are stored in some collection like

items = new List<BaseClass>();
items.add(new Class1());
items.add(new Class2());

then you can write something like

public BaseClass MyMethod(int i)
{
   return items.First(item=>item.Variable == i);
}

If you want to create a new instance with each call to MyMethod than you'll have to use switch\if (or use Reflection, but that's not a recommended approach)

Upvotes: 0

Related Questions