【问题标题】:System.StackOverflowException , when get set Properties are used?System.StackOverflowException ,何时使用 get set 属性?
【发布时间】:2012-04-05 14:56:03
【问题描述】:

在 wcfserviceLibrary.DLL 中发生了“System.StackOverflowException”类型的未处理异常

代码如下所示。

[DataContract]
public class memberdesignations
{
    [DataMember]
    public string DesigId
    {
        get { return DesigId; }
        set { DesigId = value;}
    }
    [DataMember]
    public string DesignationName
    {
        get { return DesignationName; }
        set { DesignationName = value; }
    }

}

然后我有如下类型成员指定的方法

public List<memberdesignations> memberdesignations()
    {
        List<memberdesignations> designations = new List<memberdesignations>();
        memberdesignations objmemDesignations;
        ds = objbll.Get_Member_Designations();
        DataView dv = new DataView();
        dv = ds.Tables[0].DefaultView;
        foreach (DataRowView drow in dv)
        {
            objmemDesignations = new memberdesignations();
            objmemDesignations.DesigId = drow["DesignationId"].ToString();
            objmemDesignations.DesignationName = drow["DesignationName"].ToString();
            designations.Add(objmemDesignations);
        }
        return designations;
    }

我在包含 get set 属性的类中遇到错误。

但是当我像这样修改类时,我能够摆脱错误:

 [DataContract]
public class memberdesignations
{
    [DataMember]
    public string DesigId
    {
        get;  set;
    }
    [DataMember]
    public string DesignationName
    {
        get; set;
    }
}

在搜索论坛时,我发现它的原因是Konamiman并解释了 here

我想知道Konamiman解释的两种不同属性方式之间的区别

或任何其他解释将不胜感激。

谢谢

【问题讨论】:

  • 你应该接受下面的答案。
  • @Valamas 我接受了答案,谢谢提醒。

标签: c# asp.net wcf


【解决方案1】:

问题在于,正如 Konamiman 所说,您正在递归调用属性。

假设我有一个字符串属性“DesignationName”。

public string DesignationName
{
  //Some getter to return some data
  //Some setter to set the data
}

您希望它返回什么?返回一个硬编码的字符串 _designationName 怎么样?

private string _designationName = "someName";
public string DesignationName
{
  get {return _designationName;}
  //Some setter to set the data
}

这行得通。但是如果我让它自己返回会发生什么?

public string DesignationName
{
  get {return DesignatioName;}
  //Some setter to set the data
}

嗯,它会继续调用 DesignationName,它会继续调用它自己,它会再次调用 DesignationName……等等。所有这些都将数据放在堆栈上,并一直持续下去,直到超出为堆栈分配的空间。瞧,stackoverflow。

您的上一个示例之所以有效,是因为它使用了所谓的“自动属性”,这是 .NET 3.0 的一项新功能。基本上,在幕后,它为您的属性创建支持字段,以便:

public string DesignationName
{
  get;
  set;
}

实际上编译成这样:

private string _designationName = string.Empty;
public string DesignationName
{
  get { return _designationName; }
  set { _designationName = value; }
}

【讨论】:

  • 自动实现的属性是 C# 3.0 的一个特性 :)
  • @Killnine 这样我就可以得到了;放;。谢谢你的解释。
  • 在参考了此处发布的所有答案后,我访问了 MSDN 文章,该文章对属性进行了详细说明。访问链接here
  • 是的,但最好了解幕后发生的事情。假设您使用 List 作为返回类型。了解 get;set; 很重要不会自动为您初始化此列表。所以如果你忘记在构造函数中初始化它(调用 new List()),它会返回一个空引用异常。
【解决方案2】:

您在 setter 中引用属性本身,因此它将递归调用自身。(一遍又一遍,直到堆栈溢出)

通过使用简写符号,只需 get;并设置;,您基本上是在添加一个隐含的支持字段(如支持变量)。这样您就不会触发递归调用,因为您的属性只是支持字段的包装器。

【讨论】:

  • 谢谢你的解释,现在我明白了错误的主要原因
【解决方案3】:

为两者声明私有变量:_desigId、_designationName。你处于一个无限循环的递归循环中。返回私有变量,而不是属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2014-03-31
    • 2019-04-05
    • 2012-04-10
    • 2016-08-07
    • 2012-05-11
    相关资源
    最近更新 更多