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?
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.
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.
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.
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.
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
.
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>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With