Используя типичные свойства get set в C # ... с параметрами - PullRequest
9 голосов
/ 25 октября 2008

Я хотел бы сделать то же самое в C #. Есть ли в любом случае использование свойств в C # с параметрами таким же образом, как я делал с параметром 'Key' в этом примере VB.NET?

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 ]

14 голосов
/ 25 октября 2008

Есть ли в любом случае использование свойств в C # с параметрами

Нет. Вы можете предоставить только свойство default в 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
4 голосов
/ 11 июня 2011

Более универсальным, безопасным и повторно используемым решением вашей проблемы может быть реализация универсального, «параметризованного» класса свойств, например:

    // 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 голосов
/ 25 октября 2008

«Правильный» способ сделать это в C # - создать дочерний класс специально для доступа к коллекции. Он должен содержать саму коллекцию или иметь внутренние связи с родительским классом.

3 голосов
/ 25 октября 2008

Вот пример для вас (с изменениями в соответствии с предложениями Грауенвольфа):

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"]);
    }
}
0 голосов
/ 26 октября 2008

Спасибо, Конрад, Алан, Грауэнольф,

В заключение я не могу использовать свойства C # точно так же, как в VB.NET ...: _ (Во всяком случае, ваши ответы были очень полезны для меня, и я, вероятно, передам эти идеи своим Код C #.

Помимо ответов на вопрос о свойствах, есть и другие хорошие моменты. Например,

  • Используйте TryGetValue, это быстрее. Вы запрашиваете словарь дважды.
  • Ваш установщик не должен проверять, существует ли уже значение.

Спасибо, Сёрен, тоже, что использование метода плохо вписывается в мои первоначальные цели, но большое спасибо.

0 голосов
/ 25 октября 2008

Ваш пример кода кажется мне очень странным дизайном и злоупотреблением тем, для чего предназначены свойства. Почему бы не просто метод экземпляра 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...