在 C# 中使用典型的 get set 属性...带参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/236530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using the typical get set properties in C#... with parameters
提问by Javier
I'd like to do the same in C#. Is there anyway of using properties in C# with parameters in the same way I've done with the parameter 'Key' in this VB.NET example?
我想在 C# 中做同样的事情。无论如何,在 C# 中使用带有参数的属性是否与我在此 VB.NET 示例中使用参数“Key”相同?
Private Shared m_Dictionary As IDictionary(Of String, Object) = New Dictionary(Of String, Object)
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
Thanks
谢谢
采纳答案by Konrad Rudolph
Is there anyway of using properties in C# with parameters
无论如何在 C# 中使用带有参数的属性
No. You only can provide the defaultproperty in C# with an argument, to model indexed access (as in a dictionary):
不可以。您只能在 C# 中提供带有参数的默认属性,以对索引访问进行建模(如在字典中):
public T this[string key] {
get { return m_Dictionary[key]; }
set { m_Dictionary[key] = value; }
}
Other properties can't have arguments. Use a function instead. By the way, it's recommented to do the same in VB so other .NET languages (C# …) can use your code.
其他属性不能有参数。改用函数。顺便说一句,建议在 VB 中执行相同的操作,以便其他 .NET 语言(C#...)可以使用您的代码。
By the way, your code is unnecessarily complicated. Four things:
顺便说一句,您的代码不必要地复杂。四件事:
- You don't need to escape the
String
identifier. Use the keyword directly. - Why not use
""
? - Use
TryGetValue
, it's faster. You query the dictionary twice. - Your setter doesn't have to test whether the value already exists.
- 您不需要转义
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
回答by S?ren Kuklau
Your code sample strikes me as a very strange design and an abuse of what properties are intended for. Why not just an instance method AddOrUpdateKey
:
您的代码示例让我觉得非常奇怪,并且滥用了属性的用途。为什么不只是一个实例方法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
Your property also returns String.Empty
if the key does not exist, but claims to return an Object
, nor a String
.
String.Empty
如果键不存在,您的属性也会返回,但声称返回Object
,也不返回String
。
回答by Jonathan Allen
The "proper" way to do it in C# is to create child class specifically to access the collection. It should either hold the collection itself or have internal linkages to the parent class.
在 C# 中执行此操作的“正确”方法是创建专门用于访问集合的子类。它应该持有集合本身或与父类有内部链接。
回答by Alan
Here is a sample for you (with changes along the lines of Grauenwolf's suggestions):
这是给您的示例(根据 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"]);
}
}
回答by Javier
Thanks Konrad, Alan, Grauenwolf,
感谢康拉德、艾伦、格劳恩沃尔夫,
In conclusion, I can't use C# properties exactly in the same way that in VB.NET... :_( Anyway, your answers has been very usefull to me, and I′ll probably take this ideas to my C# code.
总之,我不能像在 VB.NET 中一样使用 C# 属性... :_( 无论如何,您的回答对我非常有用,我可能会将这些想法应用到我的 C# 代码中。
In addition to the answers to the properties question, there are other good points. For example,
除了属性问题的答案之外,还有其他优点。例如,
- Use TryGetValue, it's faster. You query the dictionary twice.
- Your setter doesn't have to test whether the value already exists.
- 使用 TryGetValue,速度更快。您查询字典两次。
- 您的 setter 不必测试该值是否已存在。
Thanks S?ren, too, using a method don't fits well in my initial aims, but thanks very much.
也谢谢 S?ren,使用的方法不太适合我最初的目标,但非常感谢。
回答by Mark Jones
A more general-purpose, safer, and reusable solution to your problem might be implementing a generic, "parameterized" property class, like this:
对于您的问题,一个更通用、更安全和可重用的解决方案可能是实现一个通用的“参数化”属性类,如下所示:
// 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
}
}
You could then implement any number of properties within your public class so that clients could set/get the properties with an index, descriptor, security key, or whatever, like this:
然后,您可以在公共类中实现任意数量的属性,以便客户端可以使用索引、描述符、安全密钥或其他任何内容来设置/获取属性,如下所示:
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; }
}
}
Finally, client code would access your public class's "parameterized" properties like this:
最后,客户端代码将访问您的公共类的“参数化”属性,如下所示:
ParameterizedProperties parmProperties = new ParameterizedProperties();
parmProperties.PublicIntProp[1] = 100;
parmProperties.PublicStringProp[1] = "whatever";
int ival = parmProperties.PublicIntProp[1];
string strVal = parmProperties.PublicStringProp[1];
Sure, this seems weird, but it definitely does the trick. Besides, from a client-code perspective, it's not weird at all -- it's simple and intuitive and acts just like real properties. It doesn't break any C# rules, nor is it incompatible with other .NET managed languages. And from the class-implementer's perspective, creating a reusable, generic, "parameterized" property template class makes component coding a relative breeze, as shown here.
当然,这看起来很奇怪,但它确实可以解决问题。此外,从客户端代码的角度来看,它一点也不奇怪——它简单直观,就像真实的属性一样。它不会违反任何 C# 规则,也不会与其他 .NET 托管语言不兼容。从类实现者的角度来看,创建一个可重用的、通用的、“参数化的”属性模板类使组件编码变得轻而易举,如下所示。
NOTE: You can always override the generic property class to provide custom processing, such as indexed lookup, security-controlled property access, or whatever-the-heck you want.
注意:您始终可以覆盖通用属性类以提供自定义处理,例如索引查找、安全控制的属性访问或您想要的任何东西。
Cheers!
干杯!
Mark Jones
马克·琼斯