我有一个应用程序,它使用来自公共(public)基类的多种类型的派生类,并且有几个派生类使用泛型。应用程序经常需要遍历派生类的集合并识别特定的类类型以进行特殊处理。
问题是如何在不知道类型的情况下以简洁优雅的方式测试基类的特定泛型派生(因为它在项目中经常这样做)?
'is' 运算符不适用于此:
if (item is MyDerivedGenericClass<>) // Won't compile
为了解决这个问题,我正在考虑使用空标记接口(interface)来识别集合中的特殊类。这似乎是最干净的解决方案。
一些注意事项:
- 这是一个封闭的项目,不会成为商业分布式库。
- 标记接口(interface)标记的类被标记为永久唯一类型,并且该类型的所有派生类都将正确继承标记。
下面的例子:
public interface MarkerA { } // Empty Interface
public interface MarkerB { } // Empty Interface
public interface MarkerC { } // Empty Interface
public class BaseClass { }
public class DerivedClassA : BaseClass { }
public class DerivedClassB : BaseClass { }
public class DerivedClassC : BaseClass { }
public class DerivedSpecialClass : BaseClass { }
public class DerivedSpecialA : DerivedSpecialClass { }
public class DerivedSpecialB : DerivedSpecialClass { }
public class DerivedSpecialC : DerivedSpecialClass { }
public class DerivedSpecialGenericA<T> : DerivedSpecialClass, MarkerA { }
public class DerivedSpecialGenericB<T> : DerivedSpecialClass, MarkerB { }
public class DerivedSpecialGenericC<T> : DerivedSpecialClass, MarkerC { }
public void ProcessClasses(List<BaseClass> list)
{
// Iterate through a list of mixed classes that all derive from BaseClass
foreach (BaseClass item in list)
{
// Ideal approach, but doesn't compile:
// Try to isolate select class types to do something interesting with
if ((item is DerivedSpecialA) || (item is DerivedSpecialB) || (item is DerivedSpecialGenericB<>))
{
var specialItem = item as DerivedSpecialClass;
DoSomethingInteresting(specialItem);
Console.WriteLine(specialItem.Title);
}
// Alternative workaround that tests for the Marker instead
// Try to isolate select class types to do something interesting with
if ((item is DerivedSpecialA) || (item is DerivedSpecialB ) || (item is MarkerB))
{
var specialItem = item as DerivedSpecialClass;
DoSomethingInteresting(specialItem);
Console.WriteLine(specialItem.Title);
}
}
}
有没有人对如何解决这个问题有更好的想法?
谢谢。
最佳答案
当我需要根据对象类型编写不同的代码,并且该代码作为虚拟方法不实用时,我使用实现为返回不可变信息的虚拟属性的标识符。这更干净,并且不使用额外的实例存储,尽管通过类型参数初始化 MarkerType 会很好。
public class BaseClass
{
public abstract MarkerType { get; }
}
public enum MarkerType { A, B, C }
关于c# - 替代使用标记接口(interface)来测试派生泛型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18641070/