代码之家  ›  专栏  ›  技术社区  ›  Javier

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

  •  9
  • Javier  · 技术社区  · 16 年前

    我想用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
    

    谢谢

    6 回复  |  直到 16 年前
        1
  •  14
  •   Konrad Rudolph    16 年前

    在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
    
        2
  •  4
  •   Jonathan Allen    16 年前

        3
  •  4
  •   Mark Jones    13 年前

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

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

    干杯

    马克·琼斯

        4
  •  3
  •   Alan    16 年前

    以下是一个示例(根据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"]);
        }
    }
    
        5
  •  0
  •   Sören Kuklau Keith Boynton    16 年前

    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

        6
  •  0
  •   Javier    16 年前

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

    总之,我不能完全像在VB.NET中那样使用C#属性…:_(不管怎样,你的回答对我很有用,我可能会把这些想法带到我的C#code中。

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

    • 您的setter不必测试该值是否已经存在。