2011-01-18 68 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类库设计指南建议每个班只有一个索引。

所以在你的情况下,没有办法只用索引器来做你要求的。