Sunday, February 13, 2011

Using the typical get set properties in C#... with parameters

Hello,

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?

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

  • Is there anyway of using properties in C# with parameters

    No. You only can provide the default property in C# with an argument, to model indexed access (as in a dictionary):

    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.

    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.


    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
    
    Stimul8d : Nice answer man. Don't know why you suggest using "" instead of String.Empty though,...the original seems more explicit to me.
    Konrad Rudolph : @Stimul8d: I don’t follow. How is `""` not explicit? The only difference that I see between the two (and that, IMHO, a programmer *should* see) is that `String.Empty` is six times longer, hence it takes six times more space and takes ~ six times longer to read so it makes code six times worse. As a comparison, that’s as if we would use `Int32.Zero` instead of `0`.
    Bryan Watts : @Red-nosed unicorn: I just used that same argument last week!
  • 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:

    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.

    Javier Morillo : Hi Sören, Using a method does not allow me to use the code in this way: Example.DictionaryElement["OneKey"] = "Hello world"; Console.WriteLine(Example.DictionaryElement["OneKey"]); Thanks very much
  • 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.

  • Here is a sample for you (with changes along the lines of Grauenwolf's suggestions):

    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"]);
        }
    }
    
    From Alan
  • 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.

    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.

    Thanks Sören, too, using a method don't fits well in my initial aims, but thanks very much.

  • Very good Hasni

  • all the steps about get and set please vguys

0 comments:

Post a Comment