I have the following situation :
public interface IBaseType
{
public void InterfaceMethod ()
}
public class MyType<T> : IBaseType
{
public void InterfaceMethod () {};
public string DoSomething ()
{
if ( typeof(T) == typeof(string) ) return "String";
if ( typeof(T) == typeof(int) ) return "Int";
... so on
}
}
List<IBaseType> list = new List<IBaseType> ();
list.Add ( new MyType<int> () );
list.Add ( new MyType<long> () );
list.Add ( new MyType<string> () );
Now how can i retreive the correct generic when accessing to list elements ?
Example :
IBaseType element = list[1] ;
//here i would cast back element to MyType<long> type beacuse i would use method DoSomething()
Thanks in advance for help and sorry for my poor English.
An easy way to handle this is to add a Type
property into IBaseType
public interface IBaseType
{
void InterfaceMethod ();
Type GenericType { get; }
}
Then, in your overridden class:
public class MyType<T> : IBaseType
{
public Type GenericType { get { return typeof(T); }
}
You can also look up the Type of a generic class at run-time using Type.GetGenericArguments
, but that will involve the performance penalty of using reflection.
I agree with commenter Lasse V. Karlsen: there is something fundamentally wrong with the design if you are doing explicit type-checking and conditionally executing code in a generic class (or any class, for that matter.
Without more context, it's hard to know for sure what you should be doing here. But it seems that you have a list of IBaseType
instances, only some of which are types that implement DoSomething()
(otherwise, that method would be in the interface, right?).
In that case, I think what you should do is introduce an intermediate type, from which all your explicitly-typed (ie non-generic ) classes can inherit:
interface IBaseType { void InterfaceMethod(); }
abstract class MyType : IBaseType
{
public void InterfaceMethod() { ...implementation here... }
public abstract string DoSomething();
}
Then you'd have separate subclasses, one for each subtype:
class MyTypeInt32 : MyType
{
public override string DoSomething() { return "Int32"; }
}
class MyTypeString : MyType
{
public override string DoSomething() { return "String"; }
}
// etc.
Then you can do this:
IBaseType element = list[1];
MyType myTypeElement = element as MyType;
if (myTypeElement != null)
{
string result = myTypeElement.DoSomething();
}
That would be the proper use of polymorphism. Note the almost-complete lack of special-case, type-specific code. The above just uses the type system itself to organize the type-specific logic.
Finally, I'll note that if it happens that the InterfaceMethod()
is also a different implementation per-type, then you should just make an IMyType
interface instead of the abstract class, since each type-specific class is where the actual interface implementation should go.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.