【问题标题】:Creating a Session Helper Class that uses an array object C#创建一个使用数组对象 C# 的会话助手类
【发布时间】:2015-09-29 16:51:03
【问题描述】:

我正在使用会话助手类来跟踪多个变量。到目前为止,我一页一页都需要 30 个,当然不是一次性的。我需要将一些值从单个转换为数组。我使用的 Session 助手类如下。为简洁起见,我只展示了我们用于跟踪两个手风琴的标签索引的两个会话变量。

using System;
using System.Globalization;
using System.Linq;
using System.Web;

public class SessionHelper
{

    //Session variable constants
    public const string AccordionTop = "#tabTop";
    public const string AccordionBot = "#tabBot";


    public static T Read<T>(string variable)
    {
        object value = HttpContext.Current.Session[variable];
        if (value == null)
            return default(T);
        else
            return ((T)value);
    }

    public static void Write(string variable, object value)
    {
        HttpContext.Current.Session[variable] = value;
    }

    public static int TabTop
        {
            get
            {
                return Read<int>(AccordionTop);
            }
            set
            {
                Write(AccordionTop, value);
            }
        }

        public static int TabBot
        {
            get
            {
                return Read<int>(AccordionBot);
            }
            set
            {
                Write(AccordionBot, value);
            }
        }
}

所以在每个页面上,我都可以轻松地处理变量,如下所示:

To Write:
SessionHelper.TabTop = 1;  or  SessionHelper.TabBot = 3

To Read:
If (SessionHelper.TabTop……….)

这一切都很好。我现在想将此扩展到会话中保存的数组值。该数组包含整数、字符串和日期时间值。 对于我尝试添加的数组会话对象:

    public class SessionHelper
    {

       public const string CompInfo = "CompAccInfo";

       public static T ReadArray<T>(string variable)
       {
            object[] result = HttpContext.Current.Session[variable] as object[];
            if (result == null)
            {
                return default(T);
                //result = new object[30];
            }
            else
                return ((T)(object)result);
        }

        public static void WriteArray(string variable, object[] value)
        {
            HttpContext.Current.Session[variable] = value;
        }   


public static object[] CompDetails
        {
            get
            {
                return ReadArray<object[]>(CompInfo);
            }
            set
            {
                WriteArray(CompInfo, value);
            }
        }
}

但是当我尝试执行此操作时,我得到一个“对象引用未设置为……”错误:

    public void EGetCompanyInformation(MasterPage myMaster, int entityCode)
        {
            int prevEntity = 0;Using (sqlconnetiooo 
            .....
            //I get values here this works fine
            //Then:
            sqlr = cmd.ExecuteReader();
            sqlr.Read();
            if (sqlr.HasRows)
            {
                //Calculate accounting period adjustment.
                yearEndDiff = 12 - Convert.ToInt32(sqlr.GetDateTime(5).Month);

                    //Company Code.
                    SessionHelper.CompDetails[0] = sqlr.GetInt32(0);
                    //Company Name.
                    SessionHelper.CompDetails[1] = sqlr.GetString(1);
                    //Currency Unit.
                    SessionHelper.CompDetails[2] = sqlr.GetString(2);
                    //Base Currency Code.
                    SessionHelper.CompDetails[3] = sqlr.GetString(3);
                    //Reporting Currency Code.
                    SessionHelper.CompDetails[4] = sqlr.GetString(4);
                    //Company Year End.
                    SessionHelper.CompDetails[5] = yearEndDiff;
                    //Country Code.
                    SessionHelper.CompDetails[6] = sqlr.GetString(6);
                    //Country Name.
                    SessionHelper.CompDetails[7] = sqlr.GetString(7);
                    //Base Currency Name.
                    SessionHelper.CompDetails[8] = sqlr.GetString(8);
                    //Report Currency Name.
                    SessionHelper.CompDetails[9] = sqlr.GetString(9);
                    //ClientID.
                    SessionHelper.CompDetails[10] = sqlr.GetInt32(10);
Other code here
}

}

似乎任何 SessionHelper.CompDetails[i] 都不起作用:错误对象引用未设置为对象的实例。

【问题讨论】:

    标签: c# arrays session


    【解决方案1】:

    如果ReadArray 返回默认值(T)会怎样?它将返回空值。比通过数组内的索引访问任何对象都会导致您面临的异常。

    您的代码的用途不是很明显。

    SessionHelper.CompDetails[0] = sqlr.GetInt32(0);
    

    你想要什么? CompDetails 本身应该返回一个数组。但是你正试图用一些值立即重写它。

    如果你想访问 CompDetails 并重写它的对象,那么你必须实例化它

    int n = 10;
    SessionHelper.CompDetails = new CompDetails[n];
    

    【讨论】:

    • SessionHelper.CompDetails[0] = sqlr.GetInt32(0);
    • 这不是问题,通过将公司代码存储在 sql 数据库中并写入 index0 处的数组,它可以正常工作。该数组包含提取的其他详细信息,例如位置 1 的公司名称等。我正在寻找公共静态 T Read(string variable) 所需的更改,以便在首次访问时实例化 CompDetails 而不是 SessionHelper.CompDetails = new CompDetails[n];
    • 我正在寻找的部分在下面由“influxed”回答,我现在正在测试它的实现........p.e if(!typeof(T).IsValueType && value == null) { //如果不是值类型,则可以返回新实例。 return Activator.CreateInstance(typeof(T));
    【解决方案2】:

    default(object[]) 将始终抛出 null。因为对象数组是引用类型,任何引用类型的默认值都是空的。所以访问空值会得到Object reference not set to an instance of object

    您可以像下面这样更改旧的实现:

    public static T Read<T>(string variable, int arraySize=10)
    {
        object value = HttpContext.Current.Session[variable];
        if(typeof(T).IsArray && value == null)
        {
          //array requires size I personally prefer to have
          //differnt read method for array.
          return ((T)Activator.CreateInstance(typeof(T),arraySize));
        }
        if(!typeof(T).IsValueType && value == null)
        {
            //if it is not value type you can return new instance.
            return ((T)Activator.CreateInstance(typeof(T)));
        }        
        else if (value == null)
            return default(T);
        else
            return ((T)value);
    }
    

    并按如下方式访问 SessionHelper:

    var sessionarray = SessionHelper.Read<object[]>("myarray",15);
    ....
    // then use that sessionarray here.
    ....
    

    【讨论】:

    • 嗨,Jenish:这是我正在寻找的实现。但是,我无法越过“return Activator.CreateInstance((typeof(T));”这一行,我收到错误消息“‘T’类型的方法不能返回‘对象’类型的实例。我已经尝试过在我的旧版本中工作的类型转换(T)(对象),但在这个实现中没有任何乐趣。你能帮我解决这个问题吗?
    • 我得到 System.MissingMethodException:没有为此对象定义无参数构造函数。在同一行……
    • @Jinesh。是的,我昨天解决了这个问题。使用 public static T ReadArray(string variable, int selected, int arrayLen) { object[] value = HttpContext.Current.Session[variable] as object[]; if (!typeof(T).IsValueType && value == null) { 因为我有另一个参数可以重用其他数组的方法。非常感谢你的帮助。这是我正在寻找的确切实现。您的上一篇文章确认我们有正确的实施。非常感谢
    【解决方案3】:

    您必须先实例化 CompDetails 数组,然后才能开始为其赋值。

    if (sqlr.HasRows)
    {
        //Calculate accounting period adjustment.
        yearEndDiff = 12 - Convert.ToInt32(sqlr.GetDateTime(5).Month);
    
        // Instantiate array
        SessionHelper.CompDetails = new object[11];
    
        //Company Code.
        SessionHelper.CompDetails[0] = sqlr.GetInt32(0);
    
        // etc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      相关资源
      最近更新 更多