确定未实现该接口

时间:2016-03-22 11:06:04

标签: .net vb.net inheritance reflection interface

Interface i1
End Interface

Public Class c1
    Implements i1
End Class

Public Class c2
    Inherits c1
End Class

如何确定(使用反射)c2还没有实现i1?

4 个答案:

答案 0 :(得分:0)

我会说,在最通用的情况下,虽然它是一个肯定包含在程序集中的元信息,但它不能用.NET反射发现。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

/**
 * Created on 22.3.2016.
 *
 * @author Bojan Kseneman
 * @description A recycler view that will draw the scroll bar with a different color
 */
public class CustomScrollBarRecyclerView extends RecyclerView {

    private int scrollBarColor = Color.RED;

    public CustomScrollBarRecyclerView(Context context) {
        super(context);
    }

    public CustomScrollBarRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomScrollBarRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setScrollBarColor(@ColorInt int scrollBarColor) {
        this.scrollBarColor = scrollBarColor;
    }

    /**
     * Called by Android {@link android.view.View#onDrawScrollBars(Canvas)}
     **/
    protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
        scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
        scrollBar.setBounds(l, t, r, b);
        scrollBar.draw(canvas);
    }

    /**
     * Called by Android {@link android.view.View#onDrawScrollBars(Canvas)}
     **/
    protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
        scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
        scrollBar.setBounds(l, t, r, b);
        scrollBar.draw(canvas);
    }
}

我发现无法区分public class DerivedWithInterface : BaseClass, IInterface { } public class DerivedWithoutInterface : BaseClass { } public interface IInterface { void Method(); } public class BaseClass : IInterface { public void Method() { Console.WriteLine("C1"); } } DerivedWithInterface,但IL code is different

答案 1 :(得分:0)

要问主要问题,您可以通过以下方式检查Class是否具有已实现的接口:

Dim hasInterface As Boolean = GetType(type).GetInterfaces.Contains(GetType(MyInterface))

反思示例:

Dim ass As Assembly = Assembly.GetExecutingAssembly
Dim types As Type() = ass.GetTypes()

For Each t As Type In types

    If t.GetInterfaces.Contains(GetType(MyInterface)) Then
        Console.WrtieLine(String.Format("Found: {0}, t.Name))
    End If

Next t

答案 2 :(得分:0)

在您的情况下,您不必使用反射。 C2确实实现了你的接口i1,因为它继承自C1,因此继承了C1提供的所有方法和属性。 因此,如果C1为i1提供实现,那么C2也是如此。这是面向对象编程的神奇之处......

Public Interface I1
  Function Method1() As String
End Interface

Public Class C1
  Implements I1

  Public Function Method1() As String Implements I1.Method1
     Return "Hello"
  End Function
End Class


Public Class C2
  Inherits C1
End Class

'Somewhere in your code
Dim Test As New C2()
Test.Method1() 'It does work, so C2 Implements I1 because it inherits from C1

您还可以说,如果您想重新实现界面:

Public Class C2
  Inherits C1
  Implements I1

  'You have to declare it Overload because this function already exists
  Public Overloads Function Method1() as String Implements I1.Method1
    Return "Hello From C2"
  End Function
End Class

但它会做的是它将用C1中定义的实现替换第一个实现。而且因为它是一个替代品,所以没有办法知道它......

Dim C As New C2()
Dim T = C.GetType()
For Each I In T.GetInterfaces()
    Dim map = T.GetInterfaceMap(I)
    Dim target = map.TargetType
    MessageBox.Show(target.Name) 'Will always display C2, whether or not you reimplement it.
Next

答案 3 :(得分:0)

由于不太清楚您正在寻找什么信息,这里有两个方法:

首先,您可以使用Type.GetInterfaceMap Method检查类型是否实现了接口的方法:

public static bool TypeImplementsInterfaceMethod(this Type t, Type interfaceType)
{
    if (t.IsInterface) return false;
    if (!t.GetInterfaces().Contains(interfaceType)) return false;
    return t.GetInterfaceMap(interfaceType).TargetMethods.Any(method => method.DeclaringType == t);
}

其次,您可以检查另一个接口或basetype是否已实现该接口:

public static bool TypeDirectlyImplementsInterface(this Type t, Type interfaceType)
{
    var interfaces = t.GetInterfaces();
    if (!interfaces.Contains(interfaceType)) return false;

    if (interfaces.Where(type => type != interfaceType)
            .SelectMany(type => type.GetInterfaces())
            .Contains(interfaceType))
        return false;

    if (t.BaseType == null) return true;
    return !t.BaseType.GetInterfaces().Contains(interfaceType);
}