使用C#中的典型获取集属性。。。带参数

使用C#中的典型获取集属性。。。带参数,c#,vb.net,properties,C#,Vb.net,Properties,我想用C#做同样的事。在C#中是否有使用属性和参数的方法,就像我在这个VB.NET示例中使用参数“Key”一样 谢谢 在C#中是否有使用带有参数的属性的方法 不可以。您只能在C#中提供带有参数的默认属性,以对索引访问进行建模(如在字典中): 其他属性不能有参数。改用函数。顺便说一下,建议在VB中也这样做,以便其他.NET语言(C#…)可以使用您的代码 顺便说一句,你的代码太复杂了。四件事: 您不需要转义字符串标识符。直接使用关键字 为什么不使用“ 使用TryGetValue,速度更快。你查了两

我想用C#做同样的事。在C#中是否有使用属性和参数的方法,就像我在这个VB.NET示例中使用参数“Key”一样

谢谢

在C#中是否有使用带有参数的属性的方法

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

其他属性不能有参数。改用函数。顺便说一下,建议在VB中也这样做,以便其他.NET语言(C#…)可以使用您的代码

顺便说一句,你的代码太复杂了。四件事:

  • 您不需要转义
    字符串
    标识符。直接使用关键字
  • 为什么不使用
  • 使用
    TryGetValue
    ,速度更快。你查了两遍字典
  • 您的setter不必测试该值是否已经存在


我觉得您的代码示例是一个非常奇怪的设计,并且滥用了属性的用途。为什么不只是一个实例方法
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
如果键不存在,但声明返回
对象
,或
字符串

,则属性也会返回
字符串。如果键不存在,则返回空的
,在C中,“正确”的方法是专门创建子类来访问集合。它应该保存集合本身,或者与父类有内部链接。

下面是一个示例(按照Grauenwolf的建议进行更改):

使用系统;
使用System.Collections.Generic;
公开课考试
{
public FakeIndexedPropertyInCharp DictionaryElement{get;set;}
公开考试()
{
DictionaryElement=新FakeIndexedPropertyInSharp();
}
公共类FakeIndexedPropertyInSharp
{
私有字典m_Dictionary=新字典();
公共对象[字符串索引]
{
得到
{
客观结果;
返回m_Dictionary.TryGetValue(索引,输出结果)?结果:空;
}
设置
{
m_字典[索引]=值;
}
}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
测试t=新测试();
t、 DictionaryElement[“hello”]=“world”;
Console.WriteLine(t.DictionaryElement[“hello”]);
}
}

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

总之,我不能完全像在VB.NET中那样使用C#属性…:_(无论如何,你的答案对我很有用,我可能会把这些想法带到我的C代码中

除了财产问题的答案外,还有其他优点。例如

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

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

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

    // 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托管语言不兼容。从类实现者的角度来看,它创建了一个可重用的eneric,“参数化”属性模板类使组件编码变得相对轻松,如下所示

注意:您始终可以重写泛型属性类以提供自定义处理,例如索引查找、安全控制的属性访问或任何您想要的

干杯


Mark Jones

嗨,Sören,使用方法不允许我以这种方式使用代码:Example.DictionaryElement[“OneKey”]=“Hello world”;Console.WriteLine(Example.DictionaryElement[“OneKey”);非常感谢你的回答。不知道你为什么建议使用“”而不是字符串。虽然是空的,……原始的对我来说似乎更明确。@Stimul8d:我不明白。为什么
不明确?我看到的唯一区别是两者之间的区别(我认为程序员应该看到)这就是
String.Empty
的长度是6倍,因此它需要6倍的空间和~6倍的读取时间,因此它会使代码变得更糟6倍。作为比较,这就好像我们会使用
Int32.Zero
而不是
0
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
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"]);
    }
}
    // 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];