为泛型类型接口创建扩展方法



我想限制我的扩展方法,但是我不知道怎么做。

  1. 没有控件可以找到我的扩展方法。
  2. 任何控件都可以找到我的扩展方法。但是我不希望它被那些没有IMyProp接口的人发现。

我如何隐藏/限制我的扩展方法从那些不实现IMyProp接口的类?

附加说明:
我有多个继承自MyPropBase的类
例如:MyPropButton,MyPropTextBox..
我已经设置它自动应用MyPropBase类的不同内容,即使它们是不同的类。
通过这种方式,我的扩展方法可以对所有不同的类做同样的事情,并且它适用于所有不同的类。

public interface IMyProp<T> where T : MyPropBase
{
T MyProp { get; set; }
}
public static void DoSomething<T>(this T @this) where T : Control, IMyProp<MyPropBase>
{
//
}
private MyButton CreateMyButton()
{
MyButton btn = new();
btn.DoSomething(); //Error code: CS0311
return btn;
}
  • public static void DoSomething<T1,T2>(this T1 @this, T2 myProp) where T1 : Control, IMyProp<T2> where T2 : MyPropBase
    {
    //
    }
    private MyButton CreateMyButton()
    {
    MyButton btn = new();
    btn.DoSomething(btn.MyProp);
    return btn;
    //Button btn = new();
    //btn.DoSomething(btn.MyProp); //Error code: CS1061
    //return btn;
    }
    

    我不是100%确定你想要实现什么。我的猜测是,您希望重用一些代码,并且只向具有扩展的this参数中类型的实例公开功能。这是我编出来的:

    namespace ConsoleApp4
    {
    public static class Extensions
    {
    public static void DoSomething(this MyPropBase prop)
    {
    //
    }
    }
    }
    namespace ConsoleApp4
    {
    public interface IMyProp<T>
    where T : MyPropBase
    {
    T MyProp { get; set; }
    }
    public class MyProp01 : MyPropBase, IMyProp<MyPropBase>
    {
    public MyPropBase MyProp { get; set; }
    }
    public class MyPropBase
    {
    }
    }
    

    因为扩展方法接受MyPropBase作为this,所以它只对继承MyPropBase的类型可见。

    var prop01 = new MyProp01();
    prop01.DoSomething();
    

    这是你要找的吗?

    如果我正确理解了你的问题,你可以在扩展方法中检查对象的类型,如果对象不能从接口分配,则抛出异常。这个方法仍然允许所有控件找到扩展方法,但是对于那些没有实现接口的控件,将会有一个运行时异常。

    我正在基于@Paul的回答构建下面的代码

    namespace StackOverflow
    {
    public static class Extensions
    {
    public static void DoSomething(this MyPropBase prop)
    {
    // if (prop is IMyProp<MyPropBase>) // Cleaner way uing is keyword
    if (typeof(IMyProp<MyPropBase>).IsAssignableFrom(prop.GetType()))
    {
    // Do work
    // This code block will only be executed from class that implement the interface IMyProp
    }
    else
    {
    throw new MethodAccessException("Method not supported");
    }
    }
    }
    public interface IMyProp<T> where T : MyPropBase
    {
    T MyProp { get; set; }
    }
    public class MyPropBase
    { }
    public class MyPropButton : MyPropBase, IMyProp<MyPropBase>
    {
    public MyPropBase MyProp { get; set; }
    }
    // Test the logic
    public class Program
    {
    public static void Main()
    {
    var test2 = new MyPropButton();
    test2.DoSomething();
    var test = new MyPropBase();
    test.DoSomething();// Exception is thrown
    }
    }
    }