我正在尝试在WPF / MVVM / Entity Framework中创建尽可能通用的类结构。我正在使用Prism&统一。真的,虽然我不认为任何重要的事情,除非我能在解决方案中使用Prism / Unity。
我有一个设置完美的系统,直到我需要运行特定于Type(T)的代码。
我真正想要的是,如果类型T具有匹配的派生类,系统将使用类的非泛型版本,否则我希望它使用通用版本。
在一个超级淡化的例子中,我有一个基类:
public class BaseClass<T>
{
public T MyObject;
protected virtual int GetErrorCount()
{
int errorCount = 0;
if (MyObject == null)
errorCount++;
return errorCount;
}
}
一个子类:
public class StringClass : BaseClass<String>
{
protected override int GetErrorCount()
{
int errorCount = base.GetErrorCount();
if (MyObject != null && MyObject.Length < 5)
errorCount++;
return errorCount;
}
}
实施类:
public class ImplementationClass<T>
{
public BaseClass<T> MyBaseObject;
public ImplementationClass()
{
// If T is a string I want to use StringClass instead of the base
// And it should happen automagically
MyBaseObject = new BaseClass<T>();
}
}
我有一些想法可以解决这个问题,包括复杂的开关或者在POCO类中抛出逻辑(逻辑数据),但这不是我想做的。
我已经抛弃了使用Dictionary和一些查找类的想法,每当我需要解析实际类型时都会使用它 - 但实际上是Prism所做的,所以我认为我可以用某种方式...只是可以弄明白了。
关于如何尽可能完成此任务的任何想法?
知道了吗,对此有何反馈?我需要注意什么?
解决方案(允许更改MyBaseObject):
public static class HelperExt
{
internal static IEnumerable<Type> GetInhiritingTypes(this Type fatherT)
{
return fatherT.Assembly.GetTypes().Where(t => t.IsSubclassOf(fatherT) && !t.IsAbstract);
}
}
public class ImplementationClass<T>
{
private BaseClass<T> _myBaseObject;
public BaseClass<T> MyBaseObject
{
get { return _myBaseObject; }
set
{
Type instType = typeof(BaseDataViewModel<T>).GetInhiritingTypes().FirstOrDefault(t => t.BaseType.GetGenericArguments().Contains(typeof(T)));
if (instType != null)
SetProperty(ref _myBaseObject, (BaseClass<T>)Activator.CreateInstance(instType));
else
SetProperty(ref _myBaseObject, value);
}
}
public ImplementationClass()
{
// If T is a string I want to use StringClass instead of the base
// And it should happen automagically
MyBaseObject = new BaseClass<T>();
}
}
答案 0 :(得分:1)
你可以通过一些反思来做到这一点,首先是这个辅助函数:
public static IEnumerable<Type> GetInhiritingTypes(this Type fatherT)
{
return fatherT.Assembly.GetTypes().Where(t => t.IsSubclassOf(fatherT) && !t.IsAbstract);
}
然后:
Type genericType = typeof(string);
Type typeToInstantiate = typeof(BaseClass<String>).GetInheritingTypes().FirstOrDefault(t=>t.GetGenericsArguments().Contains(genericType));
if (typeToInstantiate != null)
MyBaseObject = (BaseClass<T>)Activator.CreateInstance(typeToInstantiate);
else
MyBaseObject = new BaseClass<T>();
但是安全性非常低&#34;在使用这样的方法。您也可以编写一个带有类名的工厂函数,并实例化该类的实例。