我想有一个类来处理来自下拉列表的数据列表,该类可以采用任何类型,因为我希望外部代码看起来像:
listProvider.For<AnEnumType>().And<AClass>.GetLists();
大于
listProvider.ForEnum<AnEnumType>().ForClass<AClass>.GetLists();
以下是示例代码
public class Foo
{
public void DoSomething<T>
{
if(typeof(T).IsEnum)
{
//Do Something
} else if (typeof(T).IsClass)
{
var bar = new Bar();
//Problem How to call bar as type T must be a reference type?
bar.GetData<T>()
}
}
}
public class Bar
{
public IProvideList<T> GetData() where T : class
{
//Do Something
}
}
public interface IProvideList<T> T : class
{
}
在编译时,编译器不知道T是一个类,但我知道它会在运行时。我可以用反思来称呼它:
bar.GetType().GetMethod("GetData").MakeGenericMethod(typeof(T));
但是,我无法在调用方法时将结果强制转换回(IProvideList),因为T必须是referenceType
有没有办法解决这个问题?
答案 0 :(得分:1)
您可以使用Bar
代替Bar<T>
,而这一切都自然而然地落在:
public void DoSomething<T>
{
if(typeof(T).IsEnum)
{
//Do Something
}
else if (typeof(T).IsClass)
{
//Here you know T
var bar = new Bar<T>();
bar.GetData()
}
}
....
public class Bar<T>
{
public IProvideList<T> GetData<T>() where T : class
{
//Do Something
}
}
答案 1 :(得分:1)
你必须在栏中使用where T : class
吗?如果不试试这个。
public class Foo
{
public void DoSomething<T>()
{
if(typeof(T).IsEnum)
{
//Do Something
} else if (typeof(T).IsClass)
{
var bar = new Bar();
//Problem How to call bar as type T must be a reference type?
bar.GetData<T>();
}
}
}
public class Bar
{
public IProvideList<T> GetData<T>() //where T : class
{
//Do Something
}
}
public interface IProvideList<T> //where T : class
{
}
答案 2 :(得分:0)
我最终设法通过反思来解决这个问题:
bar.GetType().GetMethod("GetData").MakeGenericMethod(typeof(T));
然后不尝试转换结果,而是通过反射访问结果所需的所有方法和函数:
var listProviderType = typeof (IProvideList<>).MakeGenericType(typeof (T));
var result = istProviderImplType.GetMethod("MethodINeedToCall").Invoke(listProviderImpl, null);
不完全是我所知道的最好的代码,但它实现了我想要的结果。