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参数
toType concType=genType.MakeGenericType(entityType)代码>。但是,在示例中,您尝试创建接口的实例(Activator.CreateInstance(genericType)
);这是行不通的。您需要创建实现接口的类型的实例。@Masoud:您不能创建接口的实例。您需要创建实现接口的类型的实例。如何达到这种类型取决于您的环境。