关于这个主题有很多问题,但我的版本稍有改动。
我们有以下代码:
interface IFoo { }
interface IBar : IFoo { }
class Foo : IFoo { }
class Bar : IBar { }
bool Implements_IFoo(Type type) { /* ??? */ }
现在,故事的转折:方法Implements_IFoo
只应在Type仅实现IFoo而不是从IFoo派生的任何接口时返回true。这里举例说明这种方法的一些例子:
Implements_IFoo(typeof(Foo)); // Should return true
Implements_IFoo(typeof(Bar)); // Should return false as Bar type
// implements an interface derived from IFoo
请注意,可能有很多来自IFoo的接口,您不一定知道它们的存在。
显而易见的方法是通过反射找到从IFoo派生的所有接口,然后只检查typeof(Bar).GetInterfaces()就是那里的任何一个。但我想知道是否有人能提出更优雅的解决方案。
PS问题源自我发现的一些代码,这些代码使用了对类(if(obj.GetType() == typeof(BaseClass)) { ... }
)的检查。我们正在用特定代码的接口替换类。另外,以防万一 - 我将此检查作为布尔标志实现,所以这个问题纯粹是假设的。
答案 0 :(得分:9)
我试过,因为它听起来很有趣,这适用于你的例子:
bool ImplementsIFooDirectly(Type t) {
if (t.BaseType != null && ImplementsIFooDirectly(t.BaseType)) {
return false;
}
foreach (var intf in t.GetInterfaces()) {
if (ImplementsIFooDirectly(intf)) {
return false;
}
}
return t.GetInterfaces().Any(i => i == typeof(IFoo));
}
结果:
ImplementsIFooDirectly(typeof(IFoo)); // false
ImplementsIFooDirectly(typeof(Bar)); // false
ImplementsIFooDirectly(typeof(Foo)); // true
ImplementsIFooDirectly(typeof(IBar)); // true
它不会查找从IFoo
派生的所有接口,它只是沿着继承/接口实现链向上移动,看看IFoo
是否存在于除类型的确切级别之外的任何级别
它还检测接口是否通过基类型继承。不确定这是不是你想要的。
尽管如此,正如其他人已经说过的那样,如果您真的需要这样做,那么您的设计可能会遇到问题。 (编辑:刚刚注意到你的问题纯粹是假设的。那当然没问题)))
答案 1 :(得分:3)
有关如何实施此示例的示例,请参阅以下网站;
基本上你可以使用'is'关键字来确定对象是否作为类继承栈的一部分驻留在类类型中。
class Director : Owner { }
class Developer : Employee { }
..
var dave = new Developer();
var steve = new Director();
var isEmployee = dave is Employee; // true
var isAlsoEmploye = steve is Employee; // false
符合您的示例功能:
bool Implements_Type(object instance, Type type) {
return instance is type;
}
答案 2 :(得分:2)
static bool Implements_IFoo(Type type)
{
if (typeof(IFoo).IsAssignableFrom(type.BaseType))
return false;
var barInterfaces = type.GetInterfaces()
.Where(iface => typeof(IFoo).IsAssignableFrom(iface))
.ToArray();
return barInterfaces.Length > 0
&& barInterfaces.Length == barInterfaces.Count(iface => iface == typeof(IFoo));
}
static bool Implements_IFoo_Optimized(Type type)
{
if (typeof(IFoo).IsAssignableFrom(type.BaseType))
return false;
return type.GetInterfaces()
.Where(iface => typeof(IFoo).IsAssignableFrom(iface))
.Count() == 1;
}
答案 3 :(得分:1)
这应该可以解决问题:
public bool ImplementsIFooOnly(Type type)
{
return !type.GetInterfaces().Any(t =>
{
return t is IFoo && !t.Equals(typeof(IFoo));
});
}
可能有更有效的方法。
答案 4 :(得分:0)
您是否尝试使用关键字is
?
答案 5 :(得分:0)
Type类有一个名为GetInterface的方法,你可以使用它。
bool Implements_IFoo(Type t)
{
return t.GetInterface(typeof(IFoo).Name) != null;
}