【问题标题】:property private set crashes unity属性私有集合崩溃统一
【发布时间】:2018-07-13 08:36:18
【问题描述】:

我有一个从网络获取一些数据的自定义类。
当我得到这个数据时,我想将它设置为一个属性的值,但是当我这样做时,统一崩溃了。注释行会在没有此行的情况下生成崩溃,一切正常。请参阅下面的代码:

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class GetDB
{
    private readonly Main m;
    private readonly string Url;

    public string DBData { 
        get
        {
            if(DBData == null)
                return null;
            else
                return DBData;
        } 
        private set
        {
            DBData = value;
        } 
    }

    public GetDB(Main m, string url)
    {
        this.m = m;
        this.Url = url;
    }

    public void GetServerData(){
        m.StartCoroutine(GetText(Url, (result) =>{
            this.DBData = result; //THIS LINE CRASHES UNITY
            Debug.Log(result);
        }));
    }

    IEnumerator GetText(string url, Action<string> result) {
        UnityWebRequest www = UnityWebRequest.Get(url);
        yield return www.SendWebRequest();

        if(www.isNetworkError || www.isHttpError) {
            Debug.Log(www.error);
        }
        else {
            if (result != null)
                result(www.downloadHandler.text);
        }
    }
}

我将如何解决这个问题,这里到底发生了什么?

如果有任何不清楚的地方,请告诉我,以便我澄清。

【问题讨论】:

  • DBData = value; 那是你的问题。您必须使用支持字段。
  • 我对 c# 很陌生,那么究竟什么是支持字段?

标签: c# unity3d properties coroutine


【解决方案1】:

您必须为属性使用支持字段:

string _dbData;

public string DBData
{
    get
    {
        if(_dbData == null)
            return null;
        else
            return _dbData;
    }
    private set
    {
        _dbData= value;
    }
}

属性只是 getter 和 setter 方法的语法糖。所以你可以像这样重写你的属性:

public string GetDBData()
{
    if(_dbData == null)
        return null;
    else
        return _dbData;
}

public void SetDBData(string value)
{
    _dbData = value;
}

你实现属性的方式:

public void SetDBData(string value)
{
    // you will never get out of here
    SetDBData(value);
}

【讨论】:

  • 我建议你在你的答案中添加一些关于为什么他的代码不起作用的解释,比如他这样做的方式提供了一个无限递归,然后是一个 stackoverflow
【解决方案2】:

属性充当变量的访问器。在您的案例中发生的事情基本上是一个无休止的循环 - 每当有人试图获得您的财产的价值时,它都会不断地归还财产本身。相反,您需要一个支持字段 _dbData:

private string _dbData;
public string DBData 
{ 
    get
    {
        return _dbData;
    } 
    private set
    {
        _dbData = value;
    } 
}

现在您的属性控制对该字段的访问。

【讨论】:

    【解决方案3】:

    您的访问器可以真正简化。

    正在做:

    get
    {
        if(DBData == null)
            return null;
        else
            return DBData;
    } 
    

    将提供与做完全相同的结果:

    get
    {
        return DBData; //if DBData is null, it will return null
    }
    

    所以,你可以这样写你的访问器:

    public string DBData 
    { 
        get;
        private set;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      相关资源
      最近更新 更多