C# 只有在运行时才知道类型时,如何调用具有限制的泛型

C# 只有在运行时才知道类型时,如何调用具有限制的泛型,c#,generics,casting,C#,Generics,Casting,我希望有一个类来处理下拉列表中的数据填充,该下拉列表可以采用任何类型,因为我希望外部代码如下所示: listProvider.For<AnEnumType>().And<AClass>.GetLists(); 但是,在调用该方法时,我不能将结果强制转换回(IProvideList),因为t必须是referenceType 有什么办法可以解决这个问题吗?你可以使用Bar,而不仅仅是Bar,这一切都自然而然地归结为: public void DoSomething<T

我希望有一个类来处理下拉列表中的数据填充,该下拉列表可以采用任何类型,因为我希望外部代码如下所示:

listProvider.For<AnEnumType>().And<AClass>.GetLists();
但是,在调用该方法时,我不能将结果强制转换回(IProvideList),因为t必须是referenceType


有什么办法可以解决这个问题吗?

你可以使用
Bar
,而不仅仅是
Bar
,这一切都自然而然地归结为:

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
    }
}
public void DoSomething
{
if(类型(T).IsEnum)
{
//做点什么
} 
else if(类型(T).IsClass)
{
//这是你知道的
var bar=新的bar();
bar.GetData()
}     
}
....
公共类酒吧
{
public IProviderList GetData(),其中T:class
{
//做点什么
}
}

您必须使用酒吧中的
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
{

}
公共类Foo
{
公共无效剂量测定法()
{
if(类型(T).IsEnum)
{
//做点什么
}else if(类型(T).IsClass)
{
var bar=新的bar();
//如何将条形图称为类型T必须是引用类型的问题?
bar.GetData();
}     
}
}
公共类酒吧
{
public IProviderList GetData()//其中T:class
{
//做点什么
}
}
公共接口IProvideList//其中T:class
{
}

我最终通过做反射来解决这个问题:

bar.GetType().GetMethod("GetData").MakeGenericMethod(typeof(T));
bar.GetType().GetMethod("GetData").MakeGenericMethod(typeof(T));
然后不尝试强制转换结果,而是通过反射访问结果所需的所有方法和函数,以便:

var listProviderType = typeof (IProvideList<>).MakeGenericType(typeof (T));                    
var result = istProviderImplType.GetMethod("MethodINeedToCall").Invoke(listProviderImpl, null);   
var listProviderType=typeof(iproviderList)。MakeGenericType(typeof(T));
var result=istProviderImplType.GetMethod(“MethodINeedToCall”).Invoke(listProviderImpl,null);

这不是我所知道的最好的代码,但它实现了我想要的结果。

您还没有显示您需要返回类型的目的-这将影响最佳解决方案。这将不起作用,因为在调用GetData on Bar时必须传递类型,这将导致相同的问题。为什么?你知道它的类型:它与你传递给DoSomething()方法的类型相同。这将是最简单的解决方案,但是在我的例子中我不能这样做,因为T的实现将获得一个NHibernate会话并调用session.QueryOver(),它需要T成为一个类。我没有提到这一点,因为我的问题实际上是关于泛型的,不希望它与NHibernate问题混淆。
bar.GetType().GetMethod("GetData").MakeGenericMethod(typeof(T));
var listProviderType = typeof (IProvideList<>).MakeGenericType(typeof (T));                    
var result = istProviderImplType.GetMethod("MethodINeedToCall").Invoke(listProviderImpl, null);