2009-09-24 11 views
7

Desidero creare un oggetto che funzioni in modo simile alla sessione ASP.Net.Uso personalizzato degli indicizzatori []

dire che io chiamo questo MySession oggetto, voglio fare in modo quando si fanno

mySession["Username"] = "Gav" 

Sarà o aggiungerlo a una tabella di database, se doesnt esiste o lo aggiorna se lo fa. Posso scrivere un metodo per farlo, ma non ho idea di come farlo scattare se usato con la sintassi dell'indicizzatore ([]). Non ho mai costruito un oggetto che faccia qualcosa di simile con gli indicizzatori.

Prima che qualcuno dica qualcosa, so che la sessione ASP.Net può salvare nel database ma in questo caso ho bisogno di una soluzione personalizzata leggermente più semplice.

Eventuali puntatori o esempi di utilizzo di indicizzatori in questo modo sarebbero grandi.

Grazie

+0

Eventuali duplicati di [Come faccio a sovraccaricare la piazza-staffa operatore in C#?] (https://stackoverflow.com/questions/287928/how-do-i-overload-the-square-bracket-operator-in-c) – ardila

risposta

20

in realtà è più o meno lo stesso che scrivere una proprietà tipica:

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

L'unica differenza è che usiamo la parola "questo" invece di dargli un nome proprio:

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

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

Questo è fantastico sembra proprio quello che sto cercando. Una domanda però è possibile usarla senza dover dichiarare un'istanza della classe? Ho provato a renderlo statico ma non sembra funzionare. – Gavin

+1

No, non è possibile farlo senza dichiarare un'istanza. Vedi http://stackoverflow.com/questions/154489/are-static-indexers-not-supported-in-c – Yuliy

6

Dal 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

Gli indici in C# sono proprietà con il nome this. Ecco un esempio ...

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

Se hai intenzione di usare la classe per controllare lo stato della sessione ASP.NET, cercare di implementare la classe SessionStateStoreProviderBase e IRequiresSessionState interfaccia. Si può quindi utilizzare il provider di sessione aggiungendo questo alla sezione system.web del web.config:

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

Ho visto questa tecnica utilizzata per la creazione di compressi/criptati session-stati.

1

seguito è la mia leggera variazione su MSDN esempio:

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 Classe:

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

Usage:

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(); 
     } 
Problemi correlati