转换为基础时检索通用对象类型 class
Retrieve generic object type when casted to base class
我有以下情况:
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> () );
现在如何在访问列表元素时检索正确的泛型?
示例:
IBaseType element = list[1] ;
//here i would cast back element to MyType<long> type beacuse i would use method DoSomething()
在此先感谢您的帮助,抱歉我的英语不好。
一个简单的处理方法是在 IBaseType
中添加一个 Type
属性
public interface IBaseType
{
void InterfaceMethod ();
Type GenericType { get; }
}
然后,在你重写的 class:
public class MyType<T> : IBaseType
{
public Type GenericType { get { return typeof(T); }
}
您还可以在 运行 时使用 Type.GetGenericArguments
查找泛型 class 的类型,但这会涉及使用反射的性能损失。
我同意评论者 Lasse V. Karlsen 的观点:如果您在通用 class(或任何 class , 就此而言。
没有更多上下文,很难确定您应该在这里做什么。但是 似乎 你有一个 IBaseType
实例的列表,其中只有一些是实现 DoSomething()
的类型(否则,该方法将在接口中,对吧?)。
在那种情况下,我认为你应该做的是引入一个中间类型,你所有的显式类型(即 non-generic)classes可以继承:
interface IBaseType { void InterfaceMethod(); }
abstract class MyType : IBaseType
{
public void InterfaceMethod() { ...implementation here... }
public abstract string DoSomething();
}
然后你会有单独的子classes,每个子类型一个:
class MyTypeInt32 : MyType
{
public override string DoSomething() { return "Int32"; }
}
class MyTypeString : MyType
{
public override string DoSomething() { return "String"; }
}
// etc.
那么你可以这样做:
IBaseType element = list[1];
MyType myTypeElement = element as MyType;
if (myTypeElement != null)
{
string result = myTypeElement.DoSomething();
}
这才是多态性的正确用法。请注意,几乎完全没有特殊情况、特定于类型的代码。上面只是使用类型系统本身来组织特定于类型的逻辑。
最后,我会注意到,如果碰巧 InterfaceMethod()
也是每个类型的不同实现,那么你应该只创建一个 IMyType
接口而不是抽象 class,因为每个类型特定的 class 是实际接口实现应该去的地方。
我有以下情况:
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> () );
现在如何在访问列表元素时检索正确的泛型?
示例:
IBaseType element = list[1] ;
//here i would cast back element to MyType<long> type beacuse i would use method DoSomething()
在此先感谢您的帮助,抱歉我的英语不好。
一个简单的处理方法是在 IBaseType
Type
属性
public interface IBaseType
{
void InterfaceMethod ();
Type GenericType { get; }
}
然后,在你重写的 class:
public class MyType<T> : IBaseType
{
public Type GenericType { get { return typeof(T); }
}
您还可以在 运行 时使用 Type.GetGenericArguments
查找泛型 class 的类型,但这会涉及使用反射的性能损失。
我同意评论者 Lasse V. Karlsen 的观点:如果您在通用 class(或任何 class , 就此而言。
没有更多上下文,很难确定您应该在这里做什么。但是 似乎 你有一个 IBaseType
实例的列表,其中只有一些是实现 DoSomething()
的类型(否则,该方法将在接口中,对吧?)。
在那种情况下,我认为你应该做的是引入一个中间类型,你所有的显式类型(即 non-generic)classes可以继承:
interface IBaseType { void InterfaceMethod(); }
abstract class MyType : IBaseType
{
public void InterfaceMethod() { ...implementation here... }
public abstract string DoSomething();
}
然后你会有单独的子classes,每个子类型一个:
class MyTypeInt32 : MyType
{
public override string DoSomething() { return "Int32"; }
}
class MyTypeString : MyType
{
public override string DoSomething() { return "String"; }
}
// etc.
那么你可以这样做:
IBaseType element = list[1];
MyType myTypeElement = element as MyType;
if (myTypeElement != null)
{
string result = myTypeElement.DoSomething();
}
这才是多态性的正确用法。请注意,几乎完全没有特殊情况、特定于类型的代码。上面只是使用类型系统本身来组织特定于类型的逻辑。
最后,我会注意到,如果碰巧 InterfaceMethod()
也是每个类型的不同实现,那么你应该只创建一个 IMyType
接口而不是抽象 class,因为每个类型特定的 class 是实际接口实现应该去的地方。