访问对象字段期间的访问冲突异常 [英] Access Violation Exception during access of field of Object

查看:23
本文介绍了访问对象字段期间的访问冲突异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 .Net Core 2.0、ASP.Net react 项目中使用 Linq 时遇到了一个非常奇怪的行为:

I'm encountering a realy strange behaviour when using Linq in my .Net Core 2.0, ASP.Net react project:

当访问在 LinqSelect"选择器中实例化的对象的字段时,它会抛出访问冲突异常"

When accessing a field of an object which gets instantiated inside an Linq "Select" selector, it throws an "Access Violation Exception"

重现步骤(希望如此):

Steps to reproduce (hopefully):

  • Visual Studio 2017,15.7.4
  • 创建新的 ASP.Net Core 2.0 项目
  • 选择React"模板
  • 更改 SampleDataController.cs 如下:

[HttpGet("[action]")]

public string Objects()
{
    var rng = new Random();
    var ret = Enumerable.Range(1, 5).Select(index => 
        new TableDef("User")
            .AddField(new StringField("ID", Guid.NewGuid().ToString()))
            .AddField(new StringField("Name", "User " + index.ToString()))
    );

    return "[" +
            ret.Select(x => x.ToJSONString()).Aggregate((current, next) => current + ", " + next) +
        "]";
}

  • 使用以下类:

  • With the following Classes:

    public class TableDef
    {
        public string ID { get; private set; } = Guid.NewGuid().ToString();
        public string LockedBy { get; private set; } = "";
        public string Name { get; private set; }
        public FieldDef[] Fields { get; private set; }
    
        public TableDef(string name)
        {
            Name = name;
            Fields = new FieldDef[0];
        }
    
        public TableDef AddField(FieldDef field)
        {
            field.Parent = this;
            var flds = this.Fields;
            Array.Resize(ref flds, flds.Length + 1);
            flds[flds.Length - 1] = field;
            this.Fields = flds;
            return this;
        }
    
        public string ToJSONString()
        {
            return @" { ""TableDef"": {"" 
                ""DefID"": """ + ID + @""", 
                ""DefName"": """ + Name + @""", 
                ""DefLockedBy"": """ + LockedBy + @"""}, " + 
                    Fields
                        .Select(x => ('"' + x.Name + @""" : """ + x.Value + '"'))
                        .Aggregate((current, next) => current + ", " + next) +
                "}";
        }
    }
    
    
    
    public abstract class FieldDef 
    {
        public string ID { get; protected set; } = Guid.NewGuid().ToString();
        public string Name { get; protected set; }
        public abstract string Value { get; set; }        
        public abstract string DefaultValue { get; set;  }
        public Boolean ReadOnly { get; protected set; } = false;
        public Boolean IsDirty { get; set; } = false;
        public TableDef Parent {
            get { return Parent; }
            set {
                this.Parent = value;
                ID = Parent.Name.Replace(" ", "") + "_" + Name.Replace(" ", "");
            }
        }
    }
    
    
    public class StringField : FieldDef
    {
        public override string Value {
            get { return (IsDirty) ? Value : DefaultValue; }
            set { this.Value = value; }
        }
        public override string DefaultValue { get; set; }
    
        public StringField(string name, string defaultValue)
        {
            Name = name;
            DefaultValue = defaultValue;
        }
    
        public StringField(string name, string defaultValue, Boolean readOnly)
        {
            Name = name;
            DefaultValue = defaultValue;
            ReadOnly = readOnly;
        }
    }
    

  • 当运行代码并单击获取数据"链接时,应用程序(至少在我的情况下)完全死亡,在 Visual Studio 中甚至没有错误.调试刚刚结束,给我留下了以下调试输出:

    When running the code and clicking on the "fetch data" link, the application dies (at least in my case) completely without even an error in Visual studio. The debugging just ends, leaving me with the following debug output:

    The program '[20584] dotnet.exe: Program Trace' has exited with code 0 (0x0).
    The program '[20584] dotnet.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
    The program '[20584] dotnet.exe: Managed (CoreCLR)' has exited with code -1 (0xffffffff).
    

    public TableDef AddField(FieldDef field)中注释field.Parent = this;行时,代码运行流畅.可能值得注意的是,即使我在这条线上放置了一个断点,程序也会死亡.由于这需要 2 或 3 秒,我设法从调试器的自动"中间窗口中的字段中读取了一些变量,它们看起来非常好.一旦我尝试访问父字段,应用程序就会死亡.

    When commenting the line field.Parent = this; in public TableDef AddField(FieldDef field) the code runs smoothly. What may be worth noting is, that the program dies, even though I put a Breakpoint on this line. As this takes 2 or 3 seconds, I managed to read some variables from the field in the "Auto" intermediate window in the debugger, and they look perfectly fine. As soon as i try to access the parent field, the application dies though.

    我很确定这是我自己错误地解释的一些继承的东西.

    I'm pretty sure it's some inheritance stuff falsly interpreted by myself.

    非常感谢任何帮助.谢谢.

    Any help is much appreciated. Thanks.

    推荐答案

    好的,我发现问题了.访问冲突是由于堆栈溢出而发生的,在我看来这是违反直觉的(这就是我在这里发布的原因)

    Ok, I found the problem. The access violation happens because of an stack overflow, which is in my opinion counter intuitive (which is why I'm posting it here)

    如何堆栈溢出异常当属性将值设置为自身时发生

    因为我有 getter 和 setter 的实现,所以我不能再将属性用作字段"(与默认实现"相反,仅指定 { get; set; }

    As i have an implementation of the getter and setter, I can't use the Property as "field" anymore (opposing to the "default implentation" when just specifying { get; set; }

    在实现 getter 和 setter 时需要使用单独的变量:

    One need to use separate variable when implementing getters and setters:

    private TableDef _parent;
    public TableDef Parent {
        get { return _parent; }
        set {
            this._parent = value;
            ID = Parent.Name.Replace(" ", "") + "_" + Name.Replace(" ", "");
        }
    } 
    

    恕我直言,这是违反直觉的,因为编译器可以创建"这样的代码,但作为程序员,你不能.

    Imho it's counter intuitive, because the compiler can "create" such a code, but as programmer you can't.

    这篇关于访问对象字段期间的访问冲突异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆