2011-01-18 107 views
7

在C#中可能有這樣的東西嗎?我不是很肯定:類型上的多個索引屬性?

class Library 
{ 
    public string Books[string title] 
    { 
     get{return this.GetBookByName(string title);} 
    } 

    public DateTime PublishingDates[string title] 
    { 
     get{return this.GetBookByName(string title).PublishingDate;} 
    } 
} 

,因此它可以被用作這樣的:

myLibrary.Books["V For Vendetta"] 
myLibrary.PublishingDates["V For Vendetta"] = ... 

所以,我認爲我需要在我的框架實現(通過調用它們)完整的成員方法有:

GetCustomStringValue (key) 
GetCustomIntValue (key) 
GetCustomBoolValue (key) 
GetCustomFloatValue (key) 
SetCustomStringValue (key) 
SetCustomIntValue (key) 
SetCustomBoolValue (key) 
SetCustomFloatValue (key) 

我想在我自己的類型中實現它們更清潔。

+1

這是什麼意思?爲什麼你不能只使用普通的常規方法獲取和設置? – Timwi 2011-01-18 23:53:43

+0

只是覺得有人可能會想出更好的解決方案。用這種方式看起來並不高雅,但僅僅是實驗。 – 2011-01-19 00:17:34

回答

11

你可以做到這一點的唯一方法是將有Books是返回擁有自己合適的索引類型的屬性。這裏是一個可能的辦法:

public class Indexer<TKey, TValue> 
{ 
    private Func<TKey, TValue> func; 

    public Indexer(Func<TKey, TValue> func) 
    { 
     if (func == null) 
      throw new ArgumentNullException("func"); 

     this.func = func; 
    } 

    public TValue this[TKey key] 
    { 
     get { return func(key); } 
    } 
} 

class Library 
{ 
    public Indexer<string, Book> Books { get; private set; } 
    public Indexer<string, DateTime> PublishingDates { get; private set; } 

    public Library() 
    { 
     Books = new Indexer<string, Book>(GetBookByName); 
     PublishingDates = new Indexer<string, DateTime>(GetPublishingDate); 
    } 

    private Book GetBookByName(string bookName) 
    { 
     // ... 
    } 

    private DateTime GetPublishingDate(string bookName) 
    { 
     return GetBookByName(bookName).PublishingDate; 
    } 
} 

但是你應該認真考慮提供的IDictionary<,>的實現,而不是採用這種做法,因爲這將使其他時髦的東西,比如鍵 - 值對的枚舉等

0

爲什麼不只是使用方法?

class Library 
{  
    public string Books(string title) 
    {   
     return this.GetBookByName(title); 
    }  

    public DateTime PublishingDates(string title) 
    {   
     return this.GetBookByName(title).PublishingDate; 
    } 
} 
+0

我可以但這個具體的例子有這樣的Get和Set方法,所以我認爲它會更乾淨,如果我有一個索引屬性,而不是兩個方法。它們在返回類型上有所不同,其餘部分是相同的,你傳遞一個鍵,得到int,bool,float或string類型的值。 – 2011-01-18 23:32:51

+2

我同意它不會編譯,但是@柯克的觀點仍然有效。 – 2011-01-18 23:33:12

1

不幸的是,C#不支持它。它只識別this[]屬性,編譯時它只是一個名爲Item的可索引屬性。儘管CLI支持任意數量的可索引屬性,並且可以在F#等其他語言中反映出來,您可以在其中定義自己的語言。

即使您在CIL中定義了自己的屬性,您仍然無法像C#一樣調用它們,但需要爲名爲Books的屬性get_Books(index);進行手動調用。所有的屬性都只是這樣的方法調用的語法糖。 C#只能將名爲Item的屬性識別爲可索引。

2

在C#中,索引器必須被稱爲this(請參閱http://msdn.microsoft.com/en-us/library/aa664459(v=VS.71).aspx)。您可以重載索引器,但請記住,C#不允許僅基於返回類型進行重載。所以,而你可以有:

public int this[int i] 
public string this[string s] 

你不能有:

public int this[int i] 
public string this[int i] 

的.NET類庫設計指南建議每個班只有一個索引。

所以在你的情況下,沒有辦法只用索引器來做你要求的。