簡體   English   中英

如何為許多類添加擴展方法?

[英]How can I add an extension method to many classes?

我有大約1000個類,我需要計算它的屬性數。 我有以下代碼:

    public static int NumberOfProperties()
    {
        Type type = typeof(C507);
        return type.GetProperties().Count();
    }

我可以將其復制並粘貼到每個更改typeof參數的類中,但這看起來有點單調乏味。

無論如何只需要做一個擴展方法來做var nop = C507.NumberOfProperties();

只是添加答案,建議object的完整性擴展:您還可以考慮僅為Type實現擴展:

public static int GetPropertyCount(this Type t)
{
    return t.GetProperties().Length;
}

並像這樣使用它:

typeof(C507).GetPropertyCount();

優點是您可以直接從類型中獲取屬性數,而不必先創建實例。

因此,您可以編寫使用對象或使用類型的擴展方法。

public static class ObjectExtensions
{
    public static int GetNumberOfProperties(this object value)
    {
        return value.GetType().GetProperties().Count();
    }

    public static int GetNumberOfProperties(this Type value)
    {
        return value.GetProperties().Count();
    }
}

用法:

new C507().GetNumberOfProperties();
typeof(C507).GetNumberOfProperties();

但是,您明確說明了兩件事

我可以將其復制並粘貼到每個更改typeof的類中

我有大約1000個班級

您可能不希望實例化1000個類或復制並粘貼typeof() 1000次

在這種情況下,您將需要從程序集中讀取它們。

所以類似於:

typeof(SomeClass).Assembly.GetTypes().Select(x => new
  {
       x.Name, 
       PropertyCount = x.GetType().GetProperties().Count()
  });

SomeClass是所有類所在的類(無關緊要)。

我只是簡單地將它們選擇到一個包含Types名稱和屬性計數的匿名對象中。

這個:

typeof(SomeClass).Assembly

只是一種方便的方式來獲得組裝。 還有其他方法。

Assembly.GetAssembly(typeof(Program)).GetTypes()
Assembly.GetCallingAssembly().GetTypes()
Assembly.Load("Some Assemble Ref").GetTypes()

你可以使用你找到的類型做各種各樣的事情。 如果選擇Type本身,可以稍后使用Activator.CreateInstance (如果它具有無參數構造函數)實例化它。 您也可以使用反射自動填充屬性。

你想象的不可能有一個靜態擴展方法。 話雖這么說,可以在helper類中創建一個泛型方法,如下所示。

public static int NumberOfProperties<T>()
{
    Type type = typeof(T);
    return type.GetProperties().Count();
}

給定SomeType類型,它可以被稱為int n = NumberOfProperties<SomeType>()

您可以在object上創建一個擴展方法,如下所示:

public static int PropertyCount(this object thing)
{
    return thing.GetType().GetProperties().Count();
}

並在任何你喜歡的對象上使用它:

var x = "some string";
var numProps = x.PropertyCount();

如果你想在object上有一個擴展方法:

public static ObjectExtensions
{
    public static int NumberOfProperties(this object value)
    {
        if (null == value)
          throw new ArgumentNullException("value"); // or return 0

        // Length: no need in Linq here
        return value.GetType().GetProperties().Length;
    }
}

...

C507 myObj = new C507();

// How many properties does myObj instance have?
int propCount = myObj.NumberOfProperties(); 

如果你想在Type上有一個extesnion方法:

   public static TypeExtensions
    {
        public static int NumberOfProperties(this Type value)
        {
            if (null == value)
              throw new ArgumentNullException("value"); // or return 0

            // Length: no need in Linq here
            return value.GetProperties().Length;
        }
    }

    ...


    // How many properties does C507 type have?
    int propCount = typeof(C507).NumberOfProperties(); 

有兩種方法可以做同樣的事情。

您可以將Type作為參數傳遞給方法:

public static class Helper {
    public static int NumberOfProperties(Type type)
    {
        return type.GetProperties().Count();
    }
}

您可以這樣稱呼:

// Imagine you have a class called MyClass
var result = Helper.NumberOfProperties(typeof(MyClass));

您可以使用C#中的通用系統來使語法更清晰。 這看起來像這樣:

public static class Helper {
    // Notice the argument was removed and 
    // the use of the "generic" syntax <T>
    public static int NumberOfProperties<T>()
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

你會這樣稱呼它:

var result = Helper.NumberOfProperties<MyClass>();

您還可以使用“擴展”,它允許您將其稱為屬於您的類的方法。

public static class Helper {
    // notice the `this` keyword before the parameter 
    // this is what tells C# that this is an extension method
    public static int NumberOfProperties<T>(this T @this)
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

這將允許您調用這樣的方法:

 var instance = new MyClass();
 var result = instance.NumberOfProperties();

在這個例子中,我使用了通用語法,以便它適用於任何類型的對象。 如果要將其限制為僅從特定接口或基類繼承的對象,則只需將其從使用通用語法更改為使用基類/接口。 像這樣:

public static class Helper {
    // notice the type got changed from a generic <T>
    // to specifying the exact class you want to "extend"
    public static int NumberOfProperties(this MyBaseClass @this)
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

正如@rené-vogt所提到的,您還可以創建擴展方法,以便它擴展類型Type 請參閱此主題中的答案: https//stackoverflow.com/a/38455233/984780

您可以創建一個適用於所有類型的通用擴展方法:

public static int PropertyCount<T>(this T obj)
{
    return typeof(T).GetProperties().Length;
}

這將適用於所有類型,包括應用於對象的值類型(IE結構)。 感謝piedar在這里指出我的錯誤,應用於對象仍然會將此擴展方法添加到值類型。

如果您的分類可以實現接口,那么您可以擴展該接口。

public interface IExtensible {
}

class C507 : IExtensible {

}

public static int NumberOfProperties(this IExtensible extensible)
{
    Type type = extensible.GetType();
    return type.GetProperties().Count();
}

話雖如此,擁有數百個(生成的?)類似乎是一個糟糕的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM