C#使用类型参数将对象强制转换为泛型接口

C#使用类型参数将对象强制转换为泛型接口,c#,generics,reflection,C#,Generics,Reflection,我想将对象强制转换为通用自定义接口 这是我的界面: public interface IContainer<T> { IEnumerable<T> SaveToCache(IEnumerable<T> models); } public class Container<T> { IEnumerable<T> SaveToCache(IEnumerable<T> models); } 该项目是一个PCL,因

我想将对象强制转换为通用自定义接口

这是我的界面:

public interface IContainer<T>
{
    IEnumerable<T> SaveToCache(IEnumerable<T> models);
}

public class Container<T>
{
    IEnumerable<T> SaveToCache(IEnumerable<T> models);
}

该项目是一个PCL,因此我使用了
GetRuntimeMethods

您的第二个版本不起作用,因为该方法本身不是泛型的,类是泛型的,并且您拥有的
Type
实例已经是一个实例化的泛型类型,因为您从对象实例获得它。虽然这个版本可以工作,但并不理想,因为它涉及到使用反射来调用这个方法,这个方法很慢,通常看起来像是一种代码味道

var saveMethod = container.GetType()
    .GetRuntimeMethod("SaveToCache", new Type[] { typeof(IEnumerable<>).MakeGenericType(t) })
    .Invoke (container, new object[] { items });
类可以显式实现
IContainer
,以避免调用非泛型方法,并仅在
SaveItems
方法的上下文中使用它

public class Container<T> : IContainer<T>
{
    public IEnumerable<T> SaveToCache(IEnumerable<T> models)
    {
        return models;
    }

    IEnumerable IContainer.SaveToCache(IEnumerable models)
    {

    }
}

var container = new Container<string>();
container.SaveToCache(new string[] { "" }); // The generic method is avaiable if we have an referecne to the class
container.SaveToCache(new int[] { 0 });// And this will be a compile time error as expected

IContainer icontainer = container;
icontainer.SaveToCache(new string[] { "" }); // The non genric method will be called 
icontainer.SaveToCache(new int[] { 0 });// And this will be a runtime time error 
公共类容器:IContainer
{
公共IEnumerable存储缓存(IEnumerable模型)
{
收益模型;
}
IEnumerable IContainer.SaveToCache(IEnumerable模型)
{
}
}
var container=新容器();
container.SaveToCache(新字符串[]{”“});//如果我们对该类有引用,则泛型方法是可用的
container.SaveToCache(新的int[]{0});//这将是一个编译时错误
i容器i容器=容器;
icontainer.SaveToCache(新字符串[]{”“});//将调用非genric方法
icontainer.SaveToCache(新的int[]{0});//这将是一个运行时错误

哪个类实现了您的
IContainer
接口?您不能使用运行时提供的类型强制转换(这是一个编译时操作)。特别是,编译器应该如何知道您仅在运行时提供的类型?显然,这是不可能的。但是,您可以创建一个非通用的基本接口,您的通用接口继承自该接口。容器实现IContainer,我将编辑该问题。您的问题是什么?为什么还要使用通用接口?似乎您只需要泛型方法。您的语法
typeof(IEnumerable)。MakeGenericType(t)
对我不起作用,我将尝试非泛型接口…@DanielR。你有什么特别的错误吗?我在发布后更改了它,因为没有传递参数,但它应该有效。类型“IEnumerable”(泛型)的使用需要1-typeargument。@DanielR。这很奇怪,您不能声明未初始化泛型的变量,但您可以在
typeof
中使用它们,我没有检查PCL,但这是一种语言特性,不应该依赖于此。我现在不在电脑旁,但我一到办公室就会检查one@DanielR. 我曾尝试在PCL、.NET标准库和.NET核心库中编译代码,它可以在所有版本中编译,我不知道为什么会发生此错误。
var saveMethod = container.GetType()
    .GetRuntimeMethod("SaveToCache", new Type[] { typeof(IEnumerable<>).MakeGenericType(t) })
    .Invoke (container, new object[] { items });
public interface IContainer
{
    IEnumerable SaveToCache(IEnumerable models);
}
public interface IContainer<T> : IContainer
{
    IEnumerable<T> SaveToCache(IEnumerable<T> models);
}
public class Container<T> : IContainer<T>
{
    public IEnumerable<T> SaveToCache(IEnumerable<T> models)
    {
        return models;
    }

    IEnumerable IContainer.SaveToCache(IEnumerable models)
    {

    }
}

var container = new Container<string>();
container.SaveToCache(new string[] { "" }); // The generic method is avaiable if we have an referecne to the class
container.SaveToCache(new int[] { 0 });// And this will be a compile time error as expected

IContainer icontainer = container;
icontainer.SaveToCache(new string[] { "" }); // The non genric method will be called 
icontainer.SaveToCache(new int[] { 0 });// And this will be a runtime time error