Reputation: 73
I'm trying to get all the interfaces (they are all open generic) derived from IService
that a Random
class implements. I'm sure that at least one interface Random
is implementing inherits from IService<,>
but no items is being added to the iServiceTypeInterfaces
list.
I have the following code:
var iServiceTypeInterfaces = new List<Type>();
Type iServiceGeneric = typeof(IService<,>);
foreach(Type i of Random.GetInterfaces())
{
Type currentGenericType = i.GetGenericTypeDefinition();
bool isAssignable = currentGenericType.IsAssignableTo(iServiceGeneric);
if(isAssignable)
{
iServiceTypeInterfaces.Add(i);
}
}
public interface IService<T, TSearcheable>
where T : class
where TSearcheable : class
{
Task<IEnumerable<T>> GetAll(TSearcheable searchObj);
Task<T> GetById(Guid id);
Task Create(T entity);
Task Update(T entity);
Task Delete(T entity);
}
public interface IProjectService<T, TSearcheable> : IService<T, TSearcheable>
where T : class
where TSearcheable : class
{
Task<List<Technology>> GetTechs(List<Guid> ids);
}
Upvotes: 2
Views: 766
Reputation: 73
I ended up not using the afforementioned method IsAssignableTo
and accesing all inherited interfaces from each one.
var iServiceTypeInterfaces = new List<Type>();
Type iServiceGeneric = typeof(IService<,>);
foreach(Type i of Random.GetInterfaces())
{
IEnumerable<Type> inheritedInterfaces = i.GetInterfaces().Select(i => i.GetGenericTypeDefinition())
bool inheritsFromIService = inheritedInterfaces.Contains(iServiceGeneric);
bool isIService = i.GetGenericTypeDefinition() == iServiceGeneric;
if(inheritsFromIService || isIService)
{
iServiceTypeInterfaces.Add(i);
}
}
Upvotes: 0
Reputation: 270980
IsAssignableTo
isn't designed to return true for the open type IProjectService<,>
and the open type IService<,>
. After all, IProjectService<T, U>
is not assignable to IService<V, W>
, where T
, U
, V
, W
are any type. Yes, that is the question you are asking - you are not asking whether IProjectService<T, U>
is assignable to IService<T, U>
(which it is), because both types are open types! There's no information about their type arguments at all.
I'd recommend just writing out the logic you want using LINQ. From the interfaces of Random
, you want the generic interfaces:
IService<,>
, orIService<,>
The LINQ is straightforward:
static List<Type> GetAllInterfacesAssignableTo(Type interfaceType, Type targetType) {
var genericInterface = interfaceType.GetGenericTypeDefinition();
return targetType.GetInterfaces()
.Where(x => x.IsGenericType)
.Where(x =>
x.GetGenericTypeDefinition() == genericInterface ||
x.GetInterfaces().Select(i => i.GetGenericTypeDefinition()).Contains(genericInterface)
)
.ToList();
}
Usage:
GetAllInterfacesAssignableTo(typeof(Service<>), typeof(Random))
Upvotes: 1