10

I want to create an object that will work in a similar way to ASP.Net Session.

Say I call this object mySession, I want to make it so when you do

mySession["Username"] = "Gav"

It will either add it to a database table if it doesnt exist or update it if it does. I can write a method to do this but have no idea how to get it to fire when used with the indexer syntax ([]). I've never built an object that does anything like this with indexers.

Before anyone says anything I know the ASP.Net session can save to database but in this case I need a slightly simpler customized solution.

Any pointers or examples of using indexers in this way would be great.

Thanks

Gavin
  • 17,053
  • 19
  • 64
  • 110
  • Possible duplicate of [How do I overload the square-bracket operator in C#?](https://stackoverflow.com/questions/287928/how-do-i-overload-the-square-bracket-operator-in-c) – ardila Jul 05 '17 at 09:44

5 Answers5

23

It's actually pretty much the same as writing a typical property:

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

The only difference is we use the keyword "this" instead of giving it a proper name:

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

public          object            this
^ditto          ^ditto            ^ "name"
Rex M
  • 142,167
  • 33
  • 283
  • 313
  • Thats great it looks like just what I'm after. One question though is it possible to use this without having to declare an instance of the class? I've tried making it static but it didn't seem to work. – Gavin Sep 24 '09 at 07:38
  • 1
    No you cannot do this without declaring an instance. See http://stackoverflow.com/questions/154489/are-static-indexers-not-supported-in-c – Yuliy Sep 24 '09 at 08:00
6

From the 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]);
    }
}
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
4

Indexers in C# are properties with the name this. Here's an example...

public class Session {
   //...
   public string this[string key]
   {
      get { /* get it from the database */ }
      set { /* store it in the database */ }
   }
}
Yuliy
  • 17,381
  • 6
  • 41
  • 47
1

Following is my slight variation on MSDN example:

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

Person Class:

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();
        }
Maharaj
  • 313
  • 2
  • 3
  • 14
0

If you're wanting to use your class to control ASP.NET session state, look to implement the SessionStateStoreProviderBase class and IRequiresSessionState interface. You may then use your session provider by adding this to the system.web section of your web.config:

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

I've seen this technique used for creating compressed/encrypted session-states.

Jesse C. Slicer
  • 19,901
  • 3
  • 68
  • 87