【问题标题】:Keep my list/dictionary as globally accessible保持我的列表/字典可全局访问
【发布时间】:2013-05-18 23:13:02
【问题描述】:

好的...我试图理解整个面向对象的编程,但我总是陷入死胡同。 ;)

我正在尝试使用类来存储或者更确切地说将存储大量数据。我想通过使用具有多个属性的类来存储行星数据,然后将它们保存到列表中。

我的问题是我不知道如何使这个列表全局可访问,它只能在创建它的实例中访问。

下面是我的测试环境中的一些示例代码。

OrbitalBodies.cs

class OrbitalBodies
{
    public int BodyID { get; set; }
    public string BodyName { get; set; }
    public int BodySize { get; set; }
    public int BodyX { get; set; }
    public int BodyY { get; set; }   
}

From1.cs

public void button1_Click(object sender, EventArgs e)
{
    var bodies0 = new OrbitalBodies();
    var orbitalList = new List<OrbitalBodies>();

    bodies0.BodyID = 4;
    bodies0.BodyName = "Earth";
    bodies0.BodySize = 125;
    bodies0.BodyX = -450;
    bodies0.BodyY = 75;

    orbitalList.Add(bodies0);

    bodies0.BodyID = 0;
    bodies0.BodyName = "Sol";
    bodies0.BodySize = 500;
    bodies0.BodyX = 0;
    bodies0.BodyY = 0;

    orbitalList.Add(bodies0);



    //var orbitalDic = new Dictionary<int, OrbitalBodies>();


    MessageBox.Show("Planetary body name: " + Convert.ToString(orbitalList.Count()));
}

我花了几个小时在这里和其他地方查找我的问题,但我不知道如何访问我放入列表中的信息,而不是在那个单一实例中。我的实际应用程序将包含数以万计的轨道体和许多其他数据,这些数据必须可以通过多种形式甚至其他类访问。​​

我们将不胜感激,最好的解决方案是什么?完全不同吗?!?

【问题讨论】:

  • 从应用程序设计的角度来看,您可能不希望它是全球性的。虽然一开始尝试确定它的正确范围并确保其范围在那个级别似乎更容易,但这种编程方法将您的整个应用程序变成了一堆意大利面条式代码,这些代码变得非常难以使用、理解和维护时间。另请注意,如果您在全局范围内公开此信息,则需要处理线程安全问题;那些可能是一个真正的痛苦。
  • @Servy 并不完全正确。许多东西,主要是在游戏开发中,使用静态数据来存储游戏(世界)或其他东西,这些东西在运行期间不会改变,或者需要随时随地都可以访问。
  • @MartinPerry 我并不是说你不应该让任何东西都可以在全球范围内访问,我只是说,在这种情况下,考虑到他正在做的事情,这似乎不合适,而且很少有合适的情况出现。如果不清楚,我深表歉意。
  • @Martin Perry:没有理由让它成为一个全局变量。依赖注入是前进的方向。
  • 嗯,这是一种游戏的开始。一款可以处理大量数据的游戏。不是常见的主流射击游戏……;)我需要大量数据才能一直访问,从数据库读取只有在保存和加载期间才可行。或多或少...

标签: c# list class object dictionary


【解决方案1】:

OrbitalList 设为属性:

public List<OrbitalBodies> OrbitalList {get;set;}

public void button1_Click(object sender, EventArgs e)
{
    var bodies0 = new OrbitalBodies();

    bodies0.BodyID = 4;
    bodies0.BodyName = "Earth";
    bodies0.BodySize = 125;
    bodies0.BodyX = -450;
    bodies0.BodyY = 75;

    OrbitalList.Add(bodies0);
    //...
}

//Then you can do:
doSomething(myForm.OrbitalList[0]);

【讨论】:

  • 它只是告诉我''public static List OrbitalBodyList { get;放; }'' 不一致的可访问性...比属性更难访问。
  • 您的Form 必须是public(或OrbitalList internal
  • 据我所知,表单是一个“公共部分类”
  • 为什么 OrbitalBodyList 是静态的?!
  • 好的,我解决了...被调用的类也必须是公共类而不是默认类。
【解决方案2】:

如果您只想访问“Form1”类中的列表,只需将其声明为函数外的私有成员即可:

private List<OrbitalBodies> _orbitalList;

然后将其实例化到您的“button1_Click”方法中。

如果您想在所有课程中访问您的列表,我建议您将其设为静态:

public class NewClass
{

   public static List<OrbitalBodies> OrbitalList {get; set;};

}

你这样称呼它

NewClass.OrbitalList;

希望对您有所帮助。

【讨论】:

  • 好的,我今天学到了一些东西。但是您不必对我的回答投反对票,因为我正在努力提供帮助。
  • 抱歉,我没有否决您的回答。对于我也提供了答案的问题,我不会对答案投反对票。
  • 遗憾的是,必须通过多种形式访问这些信息。 :(
  • @orel 我发现二进制对静态变量的讨伐很奇怪。谢谢 orel,这有帮助。看到静态变量如何实现目标,我认为使用它们没有任何问题。如果做某事没有问题,那么做就没有错。愚蠢的程序员。我永远不会理解他们的语法参数。
【解决方案3】:

使用设计模式Singleton

public class Globals 
{
   private List<OrbitalBodies>() orbiralList;
   private static Globals instance;

   private Globals()
   {
      this.orbiralList = new List<OrbitalBodies>();
      this.instance = NULL;
   }

   public static List<OrbitalBodies>() GetOrbitalBodies()
   { 
      if (instance == null) instance = new Globals();

      return instance.orbitaList;
   }

}

然后在您的代码中的任何地方,当您需要orbitalList 调用时

Globals.GetOrbitalBodies().<do whatever with your list>

尽量不要使用静态类,因为它们在 OO 设计方面是一团糟。

【讨论】:

  • 比静态类好。对于很多事情,它们是很好的解决方案。虽然不是这种情况,但对于初学者来说,如果他想“快速”看到一些结果,它们就足够了。
  • @MartinPerry 它与静态类并没有什么不同,至少现在是这样。唯一真正的区别是单例可以实现接口并利用多态性,但你没有这样做,所以它并没有真正变得更好。
  • @MartinPerry 为什么有对对象的静态引用和对列表的引用而不是对列表的静态引用?它有什么区别(在这种情况下)?
  • @MartinPerry 我相信你有。你可能没有这样称呼它,但你有。
【解决方案4】:

您不想要静态成员或单例(两者都会导致比解决的问题更多的问题),您需要Dependency Injection

在您的表单之外创建列表,将其传递给表单构造函数。在您需要使用列表的任何地方,从表单中传递您拥有的实例。

这样只有一个列表,需要列表的任何地方都传递一个列表(恰好是同一个列表)。

如果您及时意识到您实际上需要对两个不同的系统进行建模,您只需创建两个不同的列表,并将它们传递给两个不同的表单,一切都会继续工作,您无需返回代码删除对静态成员。

老实说,这是完全可行的,而无需进入阴暗面并延续静态/全局变量的邪恶。

注意Why static variables are considered evil

【讨论】:

  • 是的,这就像说你不需要用锤子把钉子钉进木头,你可以用玻璃瓶代替。 . .如果你管理得当。完成这项工作的正确工具仍然是锤子。
  • @james:我们可能同意不同的伙伴,我不认为全局/静态变量是一种锤子。
  • Goto 存在,并且已经确定不应该使用 (where never -> 0),例如GOTO still considered harmful?screw good practice, how bad could it be。我现在很乐意将 全局变量goto 放在同一个火箭中,然后将它们都射向太阳。
  • 您在这里谴责的是工具而不是工人,并不是 GOTO/全局变量不好,而是(通常)它们被滥用。我并不是说在日常编程中使用这些东西 - 只是重申他们确实有目的就可以完成工作如果使用正确
  • 我会很高兴地谴责工具和工作人员:) 让我们同意不同意。
猜你喜欢
  • 2021-05-06
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
  • 2016-09-23
相关资源
最近更新 更多