【问题标题】:Custom use of indexers []自定义使用索引器 []
【发布时间】:2010-11-30 23:51:47
【问题描述】:

我想创建一个与 ASP.Net Session 类似的对象。

假设我称这个对象为 mySession,我想在你这样做时这样做

mySession["Username"] = "Gav"

如果它不存在,它会将其添加到数据库表中,如果存在则更新它。我可以编写一个方法来执行此操作,但不知道如何在与索引器语法 ([]) 一起使用时触发它。我从来没有用索引器构建过这样的对象。

在任何人说话之前,我知道 ASP.Net 会话可以保存到数据库,但在这种情况下,我需要一个稍微简单的定制解决方案。

以这种方式使用索引器的任何指针或示例都会很棒。

谢谢

【问题讨论】:

标签: c# asp.net


【解决方案1】:

其实和写一个典型的属性差不多:

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

唯一的区别是我们使用关键字“this”而不是给它一个正确的名称:

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

public          object            this
^ditto          ^ditto            ^ "name"

【讨论】:

  • 太好了,它看起来正是我所追求的。一个问题是,是否可以在不必声明类实例的情况下使用它?我尝试将其设为静态,但它似乎不起作用。
  • 不,如果不声明实例,您将无法执行此操作。见stackoverflow.com/questions/154489/…
【解决方案2】:

来自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]);
    }
}

【讨论】:

    【解决方案3】:

    C# 中的索引器是名称为 this 的属性。这是一个例子......

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

    【讨论】:

      【解决方案4】:

      以下是我对 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 );
              }
          }
      }
      

      人物类:

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

      用法:

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

      【讨论】:

        【解决方案5】:

        如果您想使用您的类来控制 ASP.NET 会话状态,请实现 SessionStateStoreProviderBase 类和 IRequiresSessionState 接口。然后,您可以通过将其添加到 web.config 的 system.web 部分来使用您的会话提供程序:

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

        我已经看到这种技术用于创建压缩/加密会话状态。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-09
          • 2012-10-26
          • 1970-01-01
          • 2021-12-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多