Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic class factory problem

Tags:

c#

oop

Bellow is simplified version of the code I have:

public interface IControl<T>
{
    T Value { get; }
}

public class BoolControl : IControl<bool>
{
    public bool Value
    {
        get { return true; }
    }
}

public class StringControl : IControl<string>
{
    public string Value
    {
        get { return ""; }
    }
}
public class ControlFactory
{
    public IControl GetControl(string controlType)
    {
        switch (controlType)
        {
            case "Bool":
                return new BoolControl();
            case "String":
                return new StringControl();
        }
        return null;
    }
}

The problem is in GetControl method of ControlFactory class. Because it returns IControl and I have only IControl<T> that is a generic interface. I cannot provide T because in Bool case it's going to bool and in String case it's going to be string.

Any idea what I need to do to make it work?

like image 714
Vadim Avatar asked Apr 29 '09 19:04

Vadim


People also ask

What is generic class with example?

A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.

What is generic class in Android?

Generics are the powerful features that allow us to define classes, methods and properties which are accessible using different data types while keeping a check of the compile-time type safety. A generic type is a class or method that is parameterized over types.

Why is generic type safe?

Generics are type safe because generics are available at run time, It means the runtime knows what type of data structure you're using and can store it in memory more efficiently.

What is meant by generic class?

Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees, and so on.


2 Answers

Just derive IControl<T> from IControl.

public interface IControl<T> : IControl
{
    T Value { get; }
}

UPDATE

If I missunterstood you, and you don't want a non-generic interface, you will have to make the method GetControl() generic, too.

public IControl<T> GetControl<T>()
{
    if (typeof(T) == typeof(Boolean))
    {
        return new BoolControl(); // Will not compile.
    }
    else if (typeof(T) == typeof(String))
    {
        return new StringControl(); // Will not compile.
    }
    else
    {
        return null;
    }
}

Now you have the problem that the new controls cannot be implicitly casted to IControl<T> and you would have to make this explicit.

public IControl<T> GetControl<T>()
{
    if (typeof(T) == typeof(Boolean))
    {
        return new (IControl<T>)BoolControl();
    }
    else if (typeof(T) == typeof(String))
    {
        return (IControl<T>)new StringControl();
    }
    else
    {
        return null;
    }
}

UPDATE

Changed the cast from as IControl<T> to (IControl<T>). This is prefered because it will cause an exception if there is a bug while as IControl<T> silently returns null.

like image 178
Daniel Brückner Avatar answered Sep 19 '22 21:09

Daniel Brückner


public IControl<T> GetControl<T>()
{
    switch (typeof(T).Name)
    {
        case "Bool":
            return (IControl<T>) new BoolControl();
        case "String":
            return (IControl<T>) new StringControl();
    }
    return null;
}

Update; corrected a couple of errors in the code. Heres a call to get a class:

IControl<bool> boolControl = GetControl<bool>();
like image 30
Fredrik Mörk Avatar answered Sep 20 '22 21:09

Fredrik Mörk