2008-10-25 274 views
9

我想在C#中做同樣的事情。有沒有在C#中使用屬性的方法,參數與我在這個VB.NET例子中使用參數'Key'一樣?在C#中使用典型的get set屬性...帶參數

Private Shared m_Dictionary As IDictionary(Of String, Object) = New Dictionary(Of String, Object) 
Public Shared Property DictionaryElement(ByVal Key As String) As Object 
    Get 
     If m_Dictionary.ContainsKey(Key) Then 
      Return m_Dictionary(Key) 
     Else 
      Return [String].Empty 
     End If 
    End Get 
    Set(ByVal value As Object) 
     If m_Dictionary.ContainsKey(Key) Then 
      m_Dictionary(Key) = value 
     Else 
      m_Dictionary.Add(Key, value) 
     End If 

    End Set 
End Property 

感謝

回答

14

反正在C#與參數使用屬性的

號只能在C#提供默認財產用一個參數來模擬索引a (如在字典中):

public T this[string key] { 
    get { return m_Dictionary[key]; } 
    set { m_Dictionary[key] = value; } 
} 

其他屬性不能有參數。改用一個函數。順便說一下,它的建議是在VB中做同樣的事情,所以其他.NET語言(C#...)可以使用你的代碼。

順便說一句,你的代碼是不必要的複雜。四件事:

  • 您不需要轉義String標識符。直接使用關鍵字。
  • 爲什麼不使用""?使用TryGetValue,速度更快。您查詢詞典兩次。
  • 您的設置者不必測試該值是否已經存在。

Public Shared Property DictionaryElement(ByVal Key As String) As Object 
    Get 
     Dim ret As String 
     If m_Dictionary.TryGetValue(Key, ret) Then Return ret 
     Return "" ' Same as String.Empty! ' 
    End Get 
    Set(ByVal value As Object) 
     m_Dictionary(Key) = value 
    End Set 
End Property 
+1

好的答案男人。不知道你爲什麼建議使用「」而不是String.Empty,儘管......原來對我來說似乎更加明確。 – Stimul8d 2009-09-04 09:20:10

+4

@ Stimul8d:我不關注。 ``「`不明確?我在兩者之間看到的唯一區別(也就是說,恕我直言,一個程序員*應該看到)是`String.Empty`是六倍的長度,因此它需要六倍的空間並且需要六倍的時間來閱讀。它使代碼變壞了六倍。作爲比較,就好像我們將使用`Int32.Zero`而不是`0`。 – 2009-09-04 09:54:04

+1

鼻子獨角獸:我上星期只是用同樣的說法! – 2010-04-06 13:35:43

0

您的代碼示例給我的印象是一個非常奇怪的設計和性能怎樣打算的濫用。爲什麼不只是一個實例方法AddOrUpdateKey

​​

你的屬性還返回String.Empty如果該鍵不存在,但聲稱要返回Object,也不是String

4

在C#中完成它的「正確」方法是專門創建子類來訪問集合。它應該持有集合本身或與父類具有內部鏈接。

3

這是給你的樣品(其中沿着Grauenwolf的建議線條變化):

using System; 
using System.Collections.Generic; 

public class Test 
{ 
    public FakeIndexedPropertyInCSharp DictionaryElement { get; set; } 

    public Test() 
    { 
     DictionaryElement = new FakeIndexedPropertyInCSharp(); 
    } 

    public class FakeIndexedPropertyInCSharp 
    { 
     private Dictionary<string, object> m_Dictionary = new Dictionary<string, object>(); 

     public object this[string index] 
     { 
      get 
      { 
       object result; 
       return m_Dictionary.TryGetValue(index, out result) ? result : null; 
      } 
      set 
      { 
       m_Dictionary[index] = value; 
      } 
     } 
    } 


} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Test t = new Test(); 
     t.DictionaryElement["hello"] = "world"; 
     Console.WriteLine(t.DictionaryElement["hello"]); 
    } 
} 
0

感謝康拉德·艾倫,Grauenwolf,

總之,我不能使用C#特性正好以同樣的方式在VB.NET中:...(無論如何,你的答案對我來說非常有用,而且我可能會將這個想法應用到我的C#代碼中。

除了答案屬性問題,還有其他好點。例如,

  • 使用TryGetValue,它的速度更快。您查詢詞典兩次。
  • 您的設置者不必測試該值是否已經存在。

感謝索倫,也使用方法不要在我最初的目標非常適合,但是非常感謝。

4

一個更通用,更安全,可重複使用的解決方案,您的問題可能是實現一個通用的,「參數」屬性類,如下:

// Generic, parameterized (indexed) "property" template 
    public class Property<T> 
    { 
     // The internal property value 
     private T PropVal = default(T); 

     // The indexed property get/set accessor 
     // (Property<T>[index] = newvalue; value = Property<T>[index];) 
     public T this[object key] 
     { 
      get { return PropVal; }  // Get the value 
      set { PropVal = value; } // Set the value 
     } 
    } 

然後,您可以內實現任意數量的屬性您公共類,這樣客戶端可以設置/獲取與索引,描述符,安全密鑰,或什麼的,像這樣的屬性:

public class ParameterizedProperties 
    { 
     // Parameterized properties 
     private Property<int> m_IntProp = new Property<int>(); 
     private Property<string> m_StringProp = new Property<string>(); 

     // Parameterized int property accessor for client access 
     // (ex: ParameterizedProperties.PublicIntProp[index]) 
     public Property<int> PublicIntProp 
     { 
      get { return m_IntProp; } 
     } 

     // Parameterized string property accessor 
     // (ex: ParameterizedProperties.PublicStringProp[index]) 
     public Property<string> PublicStringProp 
     { 
      get { return m_StringProp; } 
     } 
    } 

最後,客戶端代碼將訪問你這樣的公共類的「參數」屬性:

 ParameterizedProperties parmProperties = new ParameterizedProperties(); 
     parmProperties.PublicIntProp[1] = 100; 
     parmProperties.PublicStringProp[1] = "whatever"; 
     int ival = parmProperties.PublicIntProp[1]; 
     string strVal = parmProperties.PublicStringProp[1]; 

當然,這看起來很奇怪,但它絕對有訣竅。此外,從客戶端代碼的角度來看,這並不奇怪 - 它簡單直觀,並且像真正的屬性一樣行事。它不會破壞任何C#規則,也不會與其他.NET託管語言不兼容。從類實現者的角度來看,創建一個可重用的通用「參數化」屬性模板類使組件編碼變得相對輕而易舉,如此處所示。

注意:您始終可以覆蓋通用屬性類以提供自定義處理,如索引查找,安全控制的屬性訪問或任何你想要的。

乾杯!

馬克瓊斯