11

关于这个话题有很多问题,但我有一个稍微改动过的版本。

我们有以下代码:

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)) { ... })使用了这个检查。现在,我们正在用特定代码替换类与接口。另外,以防万一 - 我将此检查作为布尔标志实现,所以这个问题纯粹是假设性的。

4

6 回答 6

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存在于类型的确切级别之外的任何级别。

它还检测接口是否通过基类型继承。不确定这是否是您想要的。

尽管如此,正如其他人已经说过的那样,如果这确实是您的要求,那么您的设计可能有问题。(编辑:刚刚注意到您的问题纯粹是假设性的。那当然没关系:))

于 2012-04-27T13:47:39.673 回答
3

有关如何实施的示例,请参见以下站点;

C#是关键字用法

本质上,您可以使用“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;
}
于 2012-04-27T13:40:28.060 回答
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;
}
于 2012-04-27T13:48:25.860 回答
1

这应该可以解决问题:

 public bool ImplementsIFooOnly(Type type)
 {
     return !type.GetInterfaces().Any(t => 
              { 
                   return t is IFoo && !t.Equals(typeof(IFoo)); 
              });
 }

可能有更有效的方法。

于 2012-04-27T13:58:29.083 回答
0

您是否尝试使用关键字is

顺便说一句,一般来说,如果您有一个逻辑案例,即某个类需要属于某个基类但不是继承者之一,那么这可能是错误的 OO 设计,可能违反了Liskov 替换原则

于 2012-04-27T13:35:10.117 回答
0

Type 类有一个可以使用的名为 GetInterface 的方法。

    bool Implements_IFoo(Type t)
    {
        return t.GetInterface(typeof(IFoo).Name) != null;
    }
于 2012-04-27T13:47:16.913 回答