C# 使用动态创建的通用接口';c语言中的s方法#

C# 使用动态创建的通用接口';c语言中的s方法#,c#,generics,reflection,interface,C#,Generics,Reflection,Interface,我有一个通用接口: public interface IGeneric<T> { Method1(T t); Method2(T t); } using System; public interface IMyInterface<T> { T Method1(T input); } public class MyImpl : IMyInterface<int> { public int Method1(int input)

我有一个通用接口:

public interface IGeneric<T>
{
    Method1(T t);
    Method2(T t);
}
using System;

public interface IMyInterface<T>
{
    T Method1(T input);
}

public class MyImpl : IMyInterface<int>
{
    public int Method1(int input)
    {
        return input * 2;
    }
}

public class Test
{
    public static void Main()
    {
        // Concrete type that implements the interface
        Type implType = typeof(MyImpl);
        // Type of generic interface
        Type genType = typeof(IMyInterface<>);
        // Interface for int
        Type concType = genType.MakeGenericType(typeof(int));
        // Create instance
        object inst = Activator.CreateInstance(implType);
        // Retrieve member that you want to call
        var member = concType.GetMethod("Method1");
        // Invoke member on instance
        var result = member.Invoke(inst, new object[] { 123 });
        Console.WriteLine("{0} --> {1}", 123, result);
    }
}

但是无法访问
Method1()

以下示例显示如何调用位于通用接口中的方法:

public interface IGeneric<T>
{
    Method1(T t);
    Method2(T t);
}
using System;

public interface IMyInterface<T>
{
    T Method1(T input);
}

public class MyImpl : IMyInterface<int>
{
    public int Method1(int input)
    {
        return input * 2;
    }
}

public class Test
{
    public static void Main()
    {
        // Concrete type that implements the interface
        Type implType = typeof(MyImpl);
        // Type of generic interface
        Type genType = typeof(IMyInterface<>);
        // Interface for int
        Type concType = genType.MakeGenericType(typeof(int));
        // Create instance
        object inst = Activator.CreateInstance(implType);
        // Retrieve member that you want to call
        var member = concType.GetMethod("Method1");
        // Invoke member on instance
        var result = member.Invoke(inst, new object[] { 123 });
        Console.WriteLine("{0} --> {1}", 123, result);
    }
}
使用系统;
公共接口IMyInterface
{
T方法1(T输入);
}
公共类MyImpl:IMyInterface
{
公共整数方法1(整数输入)
{
返回输入*2;
}
}
公开课考试
{
公共静态void Main()
{
//实现接口的具体类型
类型implType=typeof(MyImpl);
//泛型接口的类型
类型genType=typeof(IMyInterface);
//int接口
Type concType=genType.MakeGenericType(typeof(int));
//创建实例
object inst=Activator.CreateInstance(implType);
//检索要调用的成员
var成员=concType.GetMethod(“Method1”);
//在实例上调用成员
var result=member.Invoke(inst,新对象[]{123});
WriteLine(“{0}-->{1}”,123,result);
}
}
您可以运行和编辑示例。

我认为,任何知道如何解析类型的框架都是您首先要寻找的

根据您的代码块,我建议您使用以下方法。它使用
Activator
创建继承
IRepository
存储库的实例
IRepository
接口提供了将调用
Insert
方法的
result
转换为非泛型类型的功能,而无需进行反射:

public class GenericInterfaceTests
{
    [Fact]
    public void IncertsStringEntity()
    {
        // Arrange.
        var entity = "100500";

        var entityType = entity.GetType();
        var genericType = typeof(Repository<>).MakeGenericType(entityType);
        var result = Activator.CreateInstance(genericType);

        // Act.
        (result as IRepository).Insert(entity);

        // Assert.
        result.Should().BeOfType<Repository<string>>();
        var repository = result as Repository<string>; 

        repository.DataSource.Should().Contain(entity);
    }

    [Fact]
    public void InsertsIntegerEntity()
    {
        // Arrange.
        var entity = 100500;

        var entityType = entity.GetType();
        var genericType = typeof(Repository<>).MakeGenericType(entityType);
        var result = Activator.CreateInstance(genericType);

        // Act.
        (result as IRepository).Insert(entity);

        // Assert.
        result.Should().BeOfType<Repository<int>>();
        var repository = result as Repository<int>; 

        repository.DataSource.Should().Contain(entity);
    }
}

public interface IRepository<TEntity>
{
    void Insert(TEntity entity);
}

public interface IRepository
{
    void Insert(object entity);
}

public class Repository<TEntity> : IRepository<TEntity>, IRepository
{
    public List<TEntity> DataSource { get; set; }

    public Repository()
    {
        DataSource = new List<TEntity>();
    }

    public void Insert(TEntity entity)
    {
        DataSource.Add(entity);
    }

    void IRepository.Insert(object entity)
    {
        Insert((TEntity)entity);
    }
}
公共类泛型接口
{
[事实]
公共无效不公平()
{
//安排。
var entity=“100500”;
var entityType=entity.GetType();
var genericType=typeof(存储库)。MakeGenericType(entityType);
var result=Activator.CreateInstance(genericType);
//表演。
(结果为i假设)。插入(实体);
//断言。
result.Should().BeOfType();
var repository=结果作为存储库;
repository.DataSource.Should()包含(实体);
}
[事实]
公共void InsertsIntegerEntity()
{
//安排。
var实体=100500;
var entityType=entity.GetType();
var genericType=typeof(存储库)。MakeGenericType(entityType);
var result=Activator.CreateInstance(genericType);
//表演。
(结果为i假设)。插入(实体);
//断言。
result.Should().BeOfType();
var repository=结果作为存储库;
repository.DataSource.Should()包含(实体);
}
}
公共接口假定
{
无效插入(TEntity实体);
}
公共接口假定
{
无效插入(对象实体);
}
公共类存储库:IRepository,IRepository
{
公共列表数据源{get;set;}
公共存储库()
{
数据源=新列表();
}
公共无效插入(TEntity实体)
{
添加(实体);
}
void IRepository.Insert(对象实体)
{
插入((潜在)实体);
}
}

示例中的接口成员与泛型类型参数
t
没有任何关系。这也是真正的问题所在吗?如果是这样,最简单的方法是将成员移动到非泛型接口,从新接口派生出
IGeneric
,并将
Activator.CreateInstance
的返回强制转换到此基本接口。@Markus:是的,我是一个真正的问题,我有一个IRepository,它有Insert(T entity),update(T entity),…谢谢,您在代码中使用了实现接口的具体类型,我是否可能不使用它?因为我想将具体类型的创建委托给我的IoC容器,并且只使用代码中的接口。@Masoud:这应该没有什么区别;只需替换
Type implType=typeof(MyImpl)Type implType=entity.GetType()
编写代码,就像您在示例中所做的那样。无论您如何获取类型,您使用的是
typeimpltype=typeof(MyImpl)
获取
IMyInterface
具体类型,但是如果我使用
type implType=entity.GetType()
结果将是
Order
,这没有期望的结果。@Masoud:我想你必须更改
type concType=genType.makegenericype(typeof(int))行中的type参数
to
Type concType=genType.MakeGenericType(entityType)。但是,在示例中,您尝试创建接口的实例(
Activator.CreateInstance(genericType)
);这是行不通的。您需要创建实现接口的类型的实例。@Masoud:您不能创建接口的实例。您需要创建实现接口的类型的实例。如何达到这种类型取决于您的环境。