繁体   English   中英

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

[英]Creating an extension method for a generic type interface

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

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

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

补充说明:
我有多个由MyPropBase继承的类。
例如: MyPropButtonMyPropTextBox ..
我已将其设置为通过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
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM