请教:报错CS0038,嵌套类无法访问外部类非静态成员如何解决?
问题分析与解决办法
首先先看你的代码和报错:
你的代码
public class ScoreManager : MonoBehaviour { public Text recordd; string filePath; string jsonString; [System.Serializable] public class Personaje { public string nombre; public string profesion; public int nivel; public override string ToString () { return string.Format ("{0}: {1} nivel {2}", nombre, profesion, nivel); } } [System.Serializable] public class ListaPersonajes { public List<Personaje> personajes; public void Listar () { //loop cada objeto lista foreach (Personaje personaje in personajes) { Debug.Log(personaje); Debug.Log(personaje.nombre); recordd.text = "" + personaje; //// THIS LINE ERROR WHY?? } } } }
错误信息
Error CS0038: 无法通过嵌套类型'ScoreManager.ListaPersonajes'访问外部类型'ScoreManager'的非静态成员
为什么会报错?
C#里的嵌套类是独立的类型,它不会自动持有外部类(这里是ScoreManager)的实例引用。recordd是ScoreManager的非静态成员,属于某个具体的ScoreManager对象——嵌套类ListaPersonajes根本不知道你要访问哪个ScoreManager实例的recordd,所以编译器就会抛出这个错误。
解决办法(按推荐程度排序)
方法1:给嵌套类传递外部类的实例引用
修改ListaPersonajes,让它持有一个ScoreManager的实例引用,这样就能明确访问哪个对象的recordd了:
[System.Serializable] public class ListaPersonajes { public List<Personaje> personajes; // 存储外部类的实例 private ScoreManager _scoreManager; // 构造函数接收外部实例 public ListaPersonajes(ScoreManager scoreManager) { _scoreManager = scoreManager; } public void Listar () { foreach (Personaje personaje in personajes) { Debug.Log(personaje); Debug.Log(personaje.nombre); // 通过引用访问外部类成员 _scoreManager.recordd.text = "" + personaje; } } }
之后在ScoreManager里创建ListaPersonajes实例时,要把当前对象传进去:
// 比如在Start方法里 void Start() { var miLista = new ListaPersonajes(this); // 后续调用miLista.Listar()即可 }
方法2:把Listar方法移到外部类ScoreManager中
既然Listar方法需要操作ScoreManager的UI元素,把它放到外部类里更符合职责划分,代码逻辑也更清晰:
public class ScoreManager : MonoBehaviour { public Text recordd; string filePath; string jsonString; [System.Serializable] public class Personaje { public string nombre; public string profesion; public int nivel; public override string ToString () { return string.Format ("{0}: {1} nivel {2}", nombre, profesion, nivel); } } [System.Serializable] public class ListaPersonajes { public List<Personaje> personajes; } // 把Listar方法移到ScoreManager中 public void ListarPersonajes(ListaPersonajes lista) { foreach (Personaje personaje in lista.personajes) { Debug.Log(personaje); Debug.Log(personaje.nombre); recordd.text = "" + personaje; } } }
调用的时候直接在ScoreManager里调用ListarPersonajes(miLista)就行。
方法3:把recordd设为静态成员(不推荐)
如果你的ScoreManager是全局唯一的单例,可以把recordd改成静态:
public static Text recordd;
这样嵌套类里就能直接访问了,但静态成员会带来全局状态的问题——比如多个ScoreManager实例会互相覆盖,后期调试和维护容易出问题,除非你完全确定只有一个实例,否则不建议用这种方式。
内容的提问来源于stack exchange,提问作者jesus _
相关产品推荐
相关产品推荐

