Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查找类型上立即实现的接口_C#_Reflection - Fatal编程技术网

C# 查找类型上立即实现的接口

C# 查找类型上立即实现的接口,c#,reflection,C#,Reflection,在以下场景中调用typeof(Bar).GetInterfaces()时,该方法返回IFoo和IBar 接口IFoo{} 接口IBar:IFoo{} 类栏:IBar{} 有没有一种方法可以让我在工具栏上只找到即时接口(IBar) 不,编译代码中没有“立即”接口。您的类有效地编译为: class Bar : IBar, IFoo { } 你无法区分两者。您唯一能做的就是检查所有这些接口,看看是否有两个或多个接口相互继承(即使在这种情况下,您也无法真正检查类的作者是否在代码中明确提到了基接口)

在以下场景中调用typeof(Bar).GetInterfaces()时,该方法返回IFoo和IBar


接口IFoo{}
接口IBar:IFoo{}
类栏:IBar{}


有没有一种方法可以让我在工具栏上只找到即时接口(IBar)

不,编译代码中没有“立即”接口。您的类有效地编译为:

class Bar : IBar, IFoo { }
你无法区分两者。您唯一能做的就是检查所有这些接口,看看是否有两个或多个接口相互继承(即使在这种情况下,您也无法真正检查类的作者是否在代码中明确提到了基接口):

静态IEnumerable GetImmediateInterface(类型)
{
var interfaces=type.GetInterfaces();
var结果=新哈希集(接口);
foreach(接口中的i型)
result.ExceptWith(i.GetInterfaces());
返回结果;
}
公共接口IRoo{}
公共接口ISoo:IRoo{}
公共接口IMoo:ISoo{}
公共接口IGoo:IMoo{}
公共接口IFoo:IGoo{}
公共接口IBar:IFoo{}
公共类栏:IBar{}
私有无效按钮1\u单击(对象发送者,事件参数e){
Type[]interfaces=typeof(Bar).GetInterfaces();
输入immediateInterface=GetPrimaryInterface(接口);
//伊巴尔
}
公共类型GetPrimaryInterface(类型[]接口)
{
if(interfaces.Length==0)返回null;
if(interfaces.Length==1)返回接口[0];
字典类型分数=新字典();
foreach(接口中的t型)
加上(t,0);
foreach(接口中的t型)
foreach(接口中的t1类型)
if(t.IsAssignableFrom(t1))
打字分数[t1]++;
类型winner=null;
int最佳分数=-1;
foreach(typeScores中的KeyValuePair对){
如果(pair.Value>bestScore){
最佳分数=配对值;
获胜者=配对。密钥;
}
}
返回赢家;
}

这将选择具有最长继承树的接口

typeof(Bar)
  .GetInterfaces()
  .OrderByDescending(i => i.GetInterfaces().Length)
  .FirstOrDefault()

这对于我的用例来说已经足够了。

为什么要这样做?在我看来,这似乎是代码中的一个设计缺陷;)返回的数组是不确定的。@Oliver,系统将接口映射到具体类型。问题是另一种类型可能正在实现IFoo,但我们不想将IFoo接口与Bar类相关联,而是与IBar接口相关联。这是您自己的系统吗?如果是这样,您是否考虑过实现一种用于接口类关联的注册表?您还可以对配置方法进行一些约定,其中接口和类名必须遵循rule=“I”+。尽管如此,我仍然认为存在设计缺陷,因为类栏不仅是一个IBar,而且是一个IFoo。好问题。我在另一个线程上发现了。看起来很有趣的代码,但是为什么
GetPrimaryInterface
只返回一种接口类型?似乎需要潜在地返回多个接口类型才有用。
public interface IRoo { }
public interface ISoo : IRoo { }
public interface IMoo : ISoo { }
public interface IGoo : IMoo { }
public interface IFoo : IGoo { }
public interface IBar : IFoo { }
public class Bar : IBar { }

private void button1_Click(object sender, EventArgs e) {
    Type[] interfaces = typeof(Bar).GetInterfaces();    
    Type immediateInterface = GetPrimaryInterface(interfaces);
    // IBar
}

public Type GetPrimaryInterface(Type[] interfaces)
{
    if (interfaces.Length == 0) return null;
    if (interfaces.Length == 1) return interfaces[0];

    Dictionary<Type, int> typeScores = new Dictionary<Type, int>();
    foreach (Type t in interfaces)
        typeScores.Add(t, 0);

    foreach (Type t in interfaces)
        foreach (Type t1 in interfaces)
            if (t.IsAssignableFrom(t1))
                typeScores[t1]++;

    Type winner = null;
    int bestScore = -1;
    foreach (KeyValuePair<Type, int> pair in typeScores) {
        if (pair.Value > bestScore) {
            bestScore = pair.Value;
            winner = pair.Key;
        }
    }
    return winner;
}
typeof(Bar)
  .GetInterfaces()
  .OrderByDescending(i => i.GetInterfaces().Length)
  .FirstOrDefault()