2008-10-25 272 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托管语言不兼容。从类实现者的角度来看,创建一个可重用的通用“参数化”属性模板类使组件编码变得相对轻而易举,如此处所示。

注意:您始终可以覆盖通用属性类以提供自定义处理,如索引查找,安全控制的属性访问或任何你想要的。

干杯!

马克琼斯