studio - se esperaba un descriptor de acceso get o set c#
Usando las propiedades tÃpicas get set en C#... con parámetros (6)
¿Hay alguna forma de usar propiedades en C # con parámetros?
No. Solo puede proporcionar la propiedad predeterminada en C # con un argumento, para modelar el acceso indexado (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, tu código es innecesariamente complicado. Cuatro cosas:
- No necesita escapar del identificador
String
. Usa la palabra clave directamente - ¿Por qué no usar
""
? - Use
TryGetValue
, es más rápido. Usted consulta el diccionario dos veces. - Su setter no tiene que probar 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
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?
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
Aquí hay una muestra para usted (con cambios según 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"]);
}
}
Gracias Konrad, Alan, Grauenwolf,
En conclusión, no puedo usar las propiedades C # exactamente de la misma manera que en VB.NET ...: _ (De todos modos, sus respuestas me han sido muy útiles y probablemente llevaré estas ideas a mi código C #.
Además de las respuestas a la pregunta de propiedades, hay otros puntos buenos. Por ejemplo,
- Use TryGetValue, es más rápido. Usted consulta el diccionario dos veces.
- Su setter no tiene que probar si el valor ya existe.
Gracias Sören, también, usar un método no encaja bien en mis objetivos iniciales, pero muchas gracias.
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.
La muestra de tu código me parece un diseño muy extraño y un abuso de a qué propiedades se destinan. ¿Por qué no solo 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 la clave no existe, pero afirma que devuelve un Object
, ni una String
.
Una solución más general, más segura y reutilizable para su problema podría estar implementando una clase de propiedad genérica, "parametrizada", como esta:
// 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 implementar cualquier cantidad de propiedades dentro de su clase pública para que los clientes puedan establecer / obtener las propiedades con un índice, descriptor, clave de seguridad o lo que sea, de esta manera:
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; }
}
}
Finalmente, el código del cliente accedería a las propiedades "parametrizadas" de su clase pública de esta manera:
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 extraño, 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 la búsqueda indexada, el acceso a la propiedad controlado por seguridad o cualquier otra cosa que desee.
¡Aclamaciones!
Mark Jones