2009-09-24 19 views
7

Quiero crear un objeto que funcione de forma similar a la sesión ASP.Net.Uso personalizado de indexadores []

decir te llamo a esto MySession objeto, quiero que sea así cuando haces

mySession["Username"] = "Gav" 

Será bien agregarlo a una tabla de base de datos si no lo existe o actualizarlo si lo hace. Puedo escribir un método para hacer esto pero no tengo idea de cómo hacer que se dispare cuando se usa con la sintaxis del indexador ([]). Nunca he construido un objeto que haga algo como esto con los indexadores.

Antes de que alguien diga algo, sé que la sesión de ASP.Net puede guardarse en la base de datos, pero en este caso necesito una solución personalizada ligeramente más simple.

Cualquier puntero o ejemplo de usar indexadores de esta manera sería genial.

Gracias

+0

duplicado posible de [¿Cómo sobrecargar el de corchetes operador en C#?] (https://stackoverflow.com/questions/287928/how-do-i-overload-the-square-bracket-operator-in-c) – ardila

Respuesta

20

En realidad es más o menos lo mismo que escribir una propiedad típica:

public class MySessionThing 
{ 
    public object this[string key] 
    { 
     //called when we ask for something = mySession["value"] 
     get 
     { 
      return MyGetData(key); 
     } 
     //called when we assign mySession["value"] = something 
     set 
     { 
      MySetData(key, value); 
     } 
    } 

    private object MyGetData(string key) 
    { 
     //lookup and return object 
    } 

    private void MySetData(string key, object value) 
    { 
     //store the key/object pair to your repository 
    } 
} 

La única diferencia es que utilizamos la palabra clave "this" en lugar de darle un nombre propio:

public   object   MyProperty 
^access   ^(return) type ^name 
modifier 

public   object   this 
^ditto   ^ditto   ^"name" 
+0

Eso es genial, parece que es lo que busco. Sin embargo, una pregunta es ¿es posible usar esto sin tener que declarar una instancia de la clase? Intenté hacerlo estático, pero no pareció funcionar. – Gavin

+1

No, no puede hacer esto sin declarar una instancia. Consulte http://stackoverflow.com/questions/154489/are-static-indexers-not-supported-in-c – Yuliy

6

Desde el MSDN documentation:

class SampleCollection<T> 
{ 
    // Declare an array to store the data elements. 
    private T[] arr = new T[100]; 

    // Define the indexer, which will allow client code 
    // to use [] notation on the class instance itself. 
    // (See line 2 of code in Main below.)   
    public T this[int i] 
    { 
     get 
     { 
      // This indexer is very simple, and just returns or sets 
      // the corresponding element from the internal array. 
      return arr[i]; 
     } 
     set 
     { 
      arr[i] = value; 
     } 
    } 
} 

// This class shows how client code uses the indexer. 
class Program 
{ 
    static void Main(string[] args) 
    { 
     // Declare an instance of the SampleCollection type. 
     SampleCollection<string> stringCollection = new SampleCollection<string>(); 

     // Use [] notation on the type. 
     stringCollection[0] = "Hello, World"; 
     System.Console.WriteLine(stringCollection[0]); 
    } 
} 
4

Los indexadores en C# son propiedades con el nombre this. He aquí un ejemplo ...

public class Session { 
    //... 
    public string this[string key] 
    { 
     get { /* get it from the database */ } 
     set { /* store it in the database */ } 
    } 
} 
0

Si tienes intención de usar su clase para controlar el estado de sesión ASP.NET, mira a implementar la clase SessionStateStoreProviderBase y IRequiresSessionState interfaz. A continuación, puede utilizar su proveedor de sesión mediante la adición de esto a la sección system.web de su web.config:

<sessionState cookieless="true" regenerateExpiredSessionId="true" mode="Custom" customProvider="MySessionProvider"> 
     <providers> 
      <add name="MySessionProvider" type="MySession.MySessionProvider"/> 
     </providers> 
    </sessionState> 

que he visto esta técnica se utiliza para crear/sesión estados comprimidos cifrados.

1

Siguiendo es mi pequeña variación en el ejemplo de MSDN:

public class KeyValueIndexer<K,V> 
{ 
    private Dictionary<K, V> myVal = new Dictionary<K, V>(); 

    public V this[K k] 
    { 
     get 
     { 
      return myVal[k]; 
     } 
     set 
     { 
      myVal.Add(k, value); 
     } 
    } 
} 

persona Clase:

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MiddleName { get; set; } 
} 

Uso:

static void Main(string[] args) 
     { 
      KeyValueIndexer<string, object> _keyVal = new KeyValueIndexer<string, object>(); 
      _keyVal[ "Person" ] = new Person() { FirstName="Jon", LastName="Doe", MiddleName="S" }; 
      _keyVal[ "MyID" ] = 123; 
      Console.WriteLine("My name is {0} {1}, {2}", ((Person) _keyVal [ "Person" ]).FirstName, ((Person) _keyVal[ "Person" ]).MiddleName, ((Person) _keyVal[ "Person" ]).LastName); 
      Console.WriteLine("My ID is {0}", ((int) _keyVal[ "MyID" ])); 
      Console.ReadLine(); 
     } 
Cuestiones relacionadas