簡體   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