使用C#中的典型get set属性…带参数

我想在C#中做同样的事情。 有没有在C#中使用参数的属性,就像我在这个VB.NET示例中使用参数’Key’一样?

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 

谢谢

无论如何在C#中使用带参数的属性

不可以。您只能在C#中使用参数提供默认属性,以建模索引访问(如在字典中):

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

其他属性不能有参数。 请改用function。 顺便说一句,它建议在VB中执行相同的操作,以便其他.NET语言(C#…)可以使用您的代码。

顺便说一句,您的代码不必要地复杂化。 四件事:

  • 您不需要转义String标识符。 直接使用关键字。
  • 为什么不用""
  • 使用TryGetValue ,它更快。 您查询字典两次。
  • 您的setter不必测试该值是否已存在。

 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 

在C#中执行此操作的“正确”方法是专门创建子类以访问该集合。 它应该保存集合本身或者具有与父类的内部链接。

一个更通用,更安全,可重用的问题解决方案可能是实现一个通用的“参数化”属性类,如下所示:

  // Generic, parameterized (indexed) "property" template public class Property { // The internal property value private T PropVal = default(T); // The indexed property get/set accessor // (Property[index] = newvalue; value = Property[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 m_IntProp = new Property(); private Property m_StringProp = new Property(); // Parameterized int property accessor for client access // (ex: ParameterizedProperties.PublicIntProp[index]) public Property PublicIntProp { get { return m_IntProp; } } // Parameterized string property accessor // (ex: ParameterizedProperties.PublicStringProp[index]) public Property 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托管语言不兼容。 从类实现者的角度来看,创建一个可重用的,通用的“参数化”属性模板类使组件编码变得相对轻松,如此处所示。

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

干杯!

马克琼斯

以下是您的示例(根据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 m_Dictionary = new Dictionary(); 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"]); } } 

您的代码示例让我感到非常奇怪,并且滥用了什么属性。 为什么不只是一个实例方法AddOrUpdateKey

 Public Sub AddOrUpdateKey(ByVal Key As String, ByVal Value as Object) If m_Dictionary.ContainsKey(Key) Then m_Dictionary(Key) = Value Else m_Dictionary.Add(Key, Value) End If End Sub 

如果密钥不存在,您的属性也会返回String.Empty ,但声明返回Object ,也不返回String

谢谢康拉德,艾伦,格劳恩沃尔夫,

总而言之,我不能完全按照与VB.NET中相同的方式使用C#属性…:_(无论如何,你的答案对我来说非常有用,我可能会把这些想法带到我的C#代码中。

除了属性问题的答案,还有其他好处。 例如,

  • 使用TryGetValue,它更快。 您查询字典两次。
  • 您的setter不必测试该值是否已存在。

谢谢Sören,使用一种方法并不符合我最初的目标,但非常感谢。