2008-10-25 23 views
9

Me gustaría hacer lo mismo en C#. ¿Hay alguna forma de usar propiedades en C# con parámetros de la misma manera que lo he hecho con el parámetro 'Clave' en este ejemplo de VB.NET?Usando las propiedades típicas get set en C# ... con los parámetros

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 

Gracias

Respuesta

14

¿Hay alguna forma de utilizar las propiedades en C# con los parámetros

No. Sólo puede proporcionar la propiedad por defecto en C# con un argumento, para modelar un índice cceso (como en un diccionario):

public T this[string key] { 
    get { return m_Dictionary[key]; } 
    set { m_Dictionary[key] = value; } 
} 

Otras propiedades no pueden tener argumentos. Use una función en su lugar. Por cierto, se recomienda hacer lo mismo en VB para que otros lenguajes de .NET (C# ...) puedan usar su código.

Por cierto, su código es innecesariamente complicado. Cuatro cosas:

  • No necesita escapar el identificador String. Usa la palabra clave directamente
  • ¿Por qué no utilizar ""?
  • Use TryGetValue, es más rápido. Usted consulta el diccionario dos veces.
  • Su incubadora no tiene que comprobar si el valor ya existe.

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 
+1

Buena respuesta hombre. No sé por qué sugieres usar "" en lugar de String.Empty ... el original me parece más explícito. – Stimul8d

+4

@ Stimul8d: No sigo. ¿Cómo es '" "' no explícito? La única diferencia que veo entre los dos (y que, en mi humilde opinión, un programador * debería * ver) es que 'String.Empty' es seis veces más larga, por lo tanto, toma seis veces más espacio y tarda ~ seis veces más para leerlo hace que el código sea seis veces peor. Como comparación, es como si usáramos 'Int32.Zero' en lugar de' 0'. –

+1

unidireccional unicornio: ¡Acabo de usar el mismo argumento la semana pasada! –

0

Su ejemplo de código me parece un diseño muy extraño y un abuso de las propiedades que están destinados. ¿Por qué no simplemente un método de instancia 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 

Su propiedad también devuelve String.Empty si no existe la clave, pero afirma que devolver un Object, ni un String.

+0

Hola Sören, El uso de un método no me permite utilizar el código de esta manera: Example.DictionaryElement [ "OneKey"] = "Hola mundo"; Console.WriteLine (Example.DictionaryElement ["OneKey"]); Muchas gracias – Javier

4

La forma "correcta" de hacerlo en C# es crear clases para niños específicamente para acceder a la colección. Debe contener la colección en sí o tener enlaces internos a la clase principal.

3

Este es un ejemplo para usted (con los cambios en la línea de las sugerencias de 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"]); 
    } 
} 
0

Gracias Konrad, Alan, Grauenwolf,

En conclusión, no puedo utilizar C# propiedades exactamente de la misma manera que en VB.NET ...: _ (De todos modos, sus respuestas me han sido muy útiles, y probablemente lleve estas ideas a mi código C#.

Además de las respuestas a la pregunta propiedades, hay otros puntos buenos.Por ejemplo,

  • Uso TryGetValue, es más rápido. Usted consulta el diccionario dos veces.
  • Su instalador no tiene que comprobar si el valor ya existe.

Gracias Sören, también, utilizando un método de hacer no encaja bien en mis objetivos iniciales, pero muchas gracias.

4

A más de uso general, más seguro, y la solución reutilizable a su problema podría ser la implementación de una, clase de propiedad genérico "parametrizado", así:

// 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 
     } 
    } 

A continuación, puede aplicar cualquier número de propiedades dentro de su clase pública para que los clientes puedan set/get las propiedades con un índice, descriptor, clave de seguridad, o lo que sea, como esto:

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; } 
     } 
    } 

Por último, el código de cliente podría acceder a las propiedades "parametrizados" de su clase pública como esto:

 ParameterizedProperties parmProperties = new ParameterizedProperties(); 
     parmProperties.PublicIntProp[1] = 100; 
     parmProperties.PublicStringProp[1] = "whatever"; 
     int ival = parmProperties.PublicIntProp[1]; 
     string strVal = parmProperties.PublicStringProp[1]; 

Claro, esto parece raro, pero definitivamente es el truco. Además, desde una perspectiva de código de cliente, no es raro en absoluto, es simple e intuitiva y actúa como propiedades reales. No infringe ninguna regla C# ni es incompatible con otros lenguajes administrados .NET. Y desde la perspectiva del implementador de clases, la creación de una clase de plantilla de propiedades reutilizable, genérica y "parametrizada" hace que la codificación de componentes sea relativamente fácil, como se muestra aquí.

NOTA: Siempre puede anular la clase de propiedad genérica para proporcionar un procesamiento personalizado, como búsqueda indexada, acceso a propiedad controlado por seguridad o lo que sea que desee.

¡Salud!

Mark Jones

+0

+1 Gracias Mark, ¡esto se ve bien! lo comprobaré – Javier

Cuestiones relacionadas