我有以下情况:
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()
提前感谢您的帮助,对不起我的英语不好。
答案 0 :(得分:1)
处理此问题的一种简单方法是在Type
IBaseType
属性
public interface IBaseType
{
void InterfaceMethod ();
Type GenericType { get; }
}
然后,在你被覆盖的课程中:
public class MyType<T> : IBaseType
{
public Type GenericType { get { return typeof(T); }
}
您还可以使用Type.GetGenericArguments
在运行时查找泛型类的类型,但这将涉及使用反射的性能损失。
答案 1 :(得分:0)
我同意评论者Lasse V. Karlsen:如果您在泛型类(或任何类中)进行显式类型检查和有条件执行代码,那么设计会出现根本性的错误。
如果没有更多的背景,很难确定你应该在这里做什么。但似乎你有一个IBaseType
实例列表,其中只有一些是实现DoSomething()
的类型(否则,该方法将在接口中,对吧?)
在这种情况下,我认为您应该做的是引入一种中间类型,所有明确类型(即非泛型)类都可以从中继承:
interface IBaseType { void InterfaceMethod(); }
abstract class MyType : IBaseType
{
public void InterfaceMethod() { ...implementation here... }
public abstract string DoSomething();
}
然后您将拥有单独的子类,每个子类型一个:
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()
也是一个不同的per-type实现,那么你应该只创建一个IMyType
接口而不是抽象类,因为每种类型 - 特定类是实际接口实现的位置。