2013-10-29 144 views
0

我想開始是這樣的:如何共享一個靜態方法之間的幾個類

class A { ... } 
class B { ... } 
class C { ... } 

其中A,B和C有一個靜態方法MYNAME。

然後,我可以這樣做:

Console.WriteLine(A.MyName()); 
Console.WriteLine(B.MyName()); 
Console.WriteLine(C.MyName()); 

然後,我應該能夠做這樣的事了。

foreach(var type in new[] { typeof(A), typeof(B), typeof(C)) { 
    ??? Console.WriteLine(t.MyName()); 
} 

我該怎麼做?

我也希望能夠做到以下(但可能是不可能的):

??? x = new A(); 
Console.WriteLine(x.MyName()); 
x = new B(); 
Console.WriteLine(x.MyName()); 
+2

static method?你在哪裏提到方法? – wudzik

+1

基類?我也被最後一個例子弄糊塗了。什麼是't' - 你的意思是'type'? - 爲什麼你認爲MyName會在'System.Type'類型上? – vcsjones

+0

@wudzik,在我的例子中我使用了一個靜態屬性。我得到我可以添加括號,使它看起來像一個方法。 – Serge

回答

1

你在這裏要做的是將元數據與一個類型相關聯,如果知道類型,可以查詢該類型。這樣做的標準做法是使用Custom Attributes。您可以以類型安全的方式查詢這些屬性並提取每個屬性的相關信息。它們在指定繼承的方式以及是否可以應用多個相同的屬性類型方面非常靈活。它們也可以應用於除了類之外的其他東西,比如屬性或者字段,這些都很方便。


這裏有一個簡單的演示程序(空檢查並非絕對必要在這裏,但只是展示瞭如何檢查屬性是否確實存在。)請注意,提供了一個通用GetCustomAttribute擴展方法中只加入.NET 4.5。之前的版本將要求您使用非通用版本並將其轉換爲適當的屬性類型。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var types = new[] {typeof(A), typeof(B), typeof(C)}; 
     foreach (var type in types) 
     { 
      var attribute = type.GetCustomAttribute<NameAttribute>(); 
      if (attribute != null) 
       Console.WriteLine(attribute.Name); 
     } 
     Console.ReadLine(); 
    } 

    public sealed class NameAttribute : Attribute 
    { 
     public string Name { get; private set; } 

     public NameAttribute(string name) 
     { 
      Name = name; 
     } 
    } 

    [Name("A Name")] 
    public class A 
    { 
    } 

    [Name("B Name")] 
    public class B 
    { 
    } 

    [Name("C Name")] 
    public class C 
    { 
    } 
} 
+0

然後我怎樣才能在循環中檢索這些屬性的值(如我的例子中的foreach循環)? – Serge

+0

當我在4.5上時,GetCustomAttribute沒有顯示(Intelisense),因此我嘗試了4.5.1,現在它顯示出來了。它實際上可能是4.5.1功能嗎?無論如何,它返回一個枚舉,所以檢查使用Any()和使用First()的輸出。 – Serge

+0

如果你可以檢查我之前提到的要點,我可以將你的答案標記爲已接受。 – Serge

1

爲了分享你需要從基類繼承其中將包含類之間的一些靜態成員靜態成員:

public class Base 
{ 
    public static string MyName() { return "Bob"; } 
} 

public class A : Base 
{   
} 

public class B : Base 
{ 
} 

你不能做什麼你想在你的foreach循環,因爲變量t的類型爲TypeType沒有任何MyName性能。您應該使用反射來獲取MyName值:

Console.WriteLine(A.MyName()); // Bob 
Console.WriteLine(B.MyName()); // Bob 

foreach(var type in new[] { typeof(A), typeof(B) }) 
{ 
    var flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy; 
    var method = type.GetMethod("MyName", flags); 
    Console.WriteLine(method.Invoke(null, null)); 
} 

此代碼打印Bob兩種類型。

+0

A和B將以這種方式分享他們相同的靜態背景場。 – Ralf

+0

@Ralf是的,正好 –

+0

有沒有辦法避免依賴反射? – Serge

相關問題