我想在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
由于
答案 0 :(得分:14)
无论如何在C#中使用带参数的属性
没有。您只能在C#中使用参数提供默认属性,以建模索引访问(如在字典中):
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 :(得分:4)
在C#中执行此操作的“正确”方法是专门创建用于访问集合的子类。它应该保存集合本身或者具有与父类的内部链接。
答案 2 :(得分: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托管语言不兼容。从类实现者的角度来看,创建一个可重用的,通用的“参数化”属性模板类使组件编码变得相对轻松,如此处所示。
注意:您始终可以覆盖通用属性类以提供自定义处理,例如索引查找,安全性控制的属性访问或您想要的任何内容。
干杯!
马克琼斯答案 3 :(得分: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"]);
}
}
答案 4 :(得分:0)
您的代码示例让我感到非常奇怪,并且滥用了什么属性。为什么不只是一个实例方法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
。
答案 5 :(得分:0)
感谢Konrad,Alan,Grauenwolf,
总之,我不能完全按照与VB.NET相同的方式使用C#属性...:_(无论如何,你的答案对我来说非常有用,我可能会把这些想法带给我C#代码。
除了属性问题的答案外,还有其他一些好处。例如,
- 使用TryGetValue,速度更快。您查询字典两次。
- 您的setter不必测试该值是否已存在。
谢谢Sören,使用某种方法并不符合我最初的目标,但非常感谢。