我正在尝试动态创建一个继承自通用interface
的类型的实例。
例如,我有以下基接口,其中有几个其他接口派生自:
public interface IDummy { }
我有两个派生接口:
public interface IDummyDerived<T> : IDummy
{
void Foo(T value);
}
public interface ITempDerived<T> : IDummy
{
void HelloWorld(T value);
}
现在我需要一个ServiceProvider-Class,在那里我可以创建查找实现给定接口的类。每个接口(IDummyDerived和ITempDerived)只执行一次。
我的方法是:
internal class DummyServiceProvider
{
public T GetDummy<T>() where T : IDummy
{
Type baseType = typeof(IDummy);
Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => baseType.IsAssignableFrom(p) && p.IsClass).ToArray();
//now I have all classes which implements one of my interfaces
foreach(Type type in types)
{
// here I want to check if the current type is typeof(T)
// (typeof(T) == type) -> doesn't work
// (type.GetGenericTypeDefinition() == type) doesnt work
}
}
return default(T);
}
如何正确地将给定的typeof(T)
与types-array中的类型进行比较?
- 更新:
DummyServiceProvider的用法如下:
IDummyDerived<string> dummyDerived = myDummyServiceProvider.GetDummy<IDummyDerived<string>>()
答案 0 :(得分:0)
看一下这篇文章:
C# Type Comparison: Type.Equals vs operator ==
这里接受的答案是:
Console.WriteLine(type.Equals(typeof(int))); // Prints True
Console.WriteLine(type == typeof(int)); // Prints False
您的帖子与此不重复,但接受的答案可能有所帮助。
答案 1 :(得分:0)
更简单的解决方案是重写您的位置
string nameOfIDummy = typeof(IDummy).Name;
string nameOfT = typeof(T).Name;
IEnumerable<Type> classTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => p.IsClass && p.GetInterface(nameOfIDummy) != null && p.GetInterface(nameOfT ) != null);
也许你可以写下你需要的东西,我没有得到用例,对我来说这似乎是一件奇怪的事情。
答案 2 :(得分:0)
您正在检查base generic interface type
与derived type
之间的平等,这始终是错误的:
请参阅以下代码
using System;
using System.Reflection;
using System.Linq;
namespace AssemblyLoadRefelectionExp
{
public class MyClass
{
public string Key { get; set; }
}
public interface IDummy { }
public interface IDummyDerived<T> : IDummy
{
void Foo(T value);
}
public interface ITempDerived<T> : IDummy
{
void HelloWorld(T value);
}
public class DummyDerived<T> : IDummyDerived<T>
{
public void Foo(T value)
{
Console.WriteLine("DummyDerived`1 ->Foo");
}
}
public class AnotherDummy : IDummyDerived<string>
{
public void Foo(string value)
{
Console.WriteLine("AnotherDummy -> Foo");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine($"Is {typeof(DummyDerived<MyClass>)} equal to {typeof(IDummyDerived<MyClass>)} : {CheckType<DummyDerived<MyClass>>(typeof(IDummyDerived<MyClass>))}");
Console.WriteLine("---------------------------------");
GetDummy<IDummyDerived<string>>();
Console.ReadLine();
}
public static bool CheckType<T>(Type type)
{
return typeof(T) == type ? true : false;
}
public static T GetDummy<T>() where T : IDummy
{
Type baseType = typeof(IDummy);
Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => baseType.IsAssignableFrom(p) && p.IsClass).ToArray();
//now I have all classes which implements one of my interfaces
foreach (Type type in types)
{
Console.WriteLine($"Is {type.Name} assignable from {typeof(T)} : {typeof(T).IsAssignableFrom(type)}");
}
return default(T);
}
}
}
将输出生成为
是AssemblyLoadRefelectionExp.DummyDerived
1[AssemblyLoadRefelectionExp.MyClass] equal to AssemblyLoadRefelectionExp.IDummyDerived
1 [AssemblyLoadRefelectionExp.MyClass]:False`DummyDerived
1 assignable from AssemblyLoadRefelectionExp.IDummyDerived
1 [System.String]:False可从AssemblyLoadRefelectionExp.IDummyDerived`1 [System.String]分配的AnotherDummy:True
如果您签入上面的代码,要检查派生类型的基本类型,我使用IsAssignableFrom
方法,因为GetDummy
方法正在调用base generic interface type
。 IsAssignableFrom
验证可以将指定类型的实例分配给当前类型的实例。