简体   繁体   English

我应该在哪里存储不同类型的值?

[英]Where should I store different types of value?

After Python and JavaScript I started using C# and can't understand some basic concepts.在 Python 和 JavaScript 之后我开始使用 C# 并且无法理解一些基本概念。

In Python and JavaScript I used to store everything in a heap without thinking about the type of object.在 Python 和 JavaScript 中,我曾经将所有内容存储在堆中,而不考虑 object 的类型。 But in C# I can't create Dictionary or List with different type of object.但在 C# 中,我无法使用不同类型的 object 创建DictionaryList

I want to store some mouse and keyboard events.我想存储一些鼠标和键盘事件。 For that, I use instances of class, like this:为此,我使用 class 的实例,如下所示:

class UserActionEvent
{
    public MacroEventType Type;
    public int[] MouseCoordinate = new int[2];
    public string MouseKey;
    public string KeyBoardKey;
    public int TimeSinceLastEvent;
}

And all instances is saved in Queue .所有实例都保存在Queue中。 But I worry whether it is normal to store several thousand objects like this?但是我担心这样存储几千个对象是否正常? Maybe there is a more universal way to store data of different types?也许有一种更通用的方式来存储不同类型的数据?

Storage in C# is not much different from Python in JavaScript in that it uses a garbage collected heap (of course every runtime has its own way of implementing the GC). C# 中的存储与 JavaScript 中的 Python 没有太大区别,因为它使用垃圾收集堆(当然每个运行时都有自己的实现 GC 的方式)。 So for "normal" classes you can just go ahead and treat them as you would in JS.因此,对于“普通”类,您可以提前 go 并像在 JS 中一样对待它们。

C#, however, also has the concept of value types , which are typically allocated on the stack.然而,C# 也有值类型的概念,通常在堆栈上分配。 The stack has a much more limited space than the heap, so this is where you need to be a bit more careful, but it is unlikely that you accidentally allocate a large amount of stack space, since collection types are all reference types (with the exception of the more exotic stackalloc arrays that you should stay away from unless you are sure what you are doing).堆栈的空间比堆要有限得多,因此在这方面您需要更加小心,但您不太可能意外分配大量堆栈空间,因为集合类型都是引用类型(使用除了更奇特的stackalloc arrays 之外,除非您确定自己在做什么,否则您应该远离)。 When passing value types between methods, they are copied, but it is also possible to pass them by reference (for example by casting to object ).在方法之间传递值类型时,它们会被复制,但也可以通过引用传递它们(例如通过转换为object )。 This will wrap the value type in a reference type, a process called boxing (the opposite process is called unboxing ).这会将值类型包装在引用类型中,这个过程称为装箱(相反的过程称为拆箱)。

To create a value type, use struct instead of class .要创建值类型,请使用struct而不是class In your example above, using a value type for the mouse coordinate, eg在上面的示例中,使用鼠标坐标的值类型,例如

struct Point {
    public int X, Y;
}

instead of an int array would likely save memory (and GC CPU time) since in your example you would have to allocate a reference object (the array) to hold only eight bytes (the two ints).而不是 int 数组可能会节省 memory (和 GC CPU 时间),因为在您的示例中,您必须分配一个引用 object (数组)以仅保存八个字节(两个整数)。 But this only matters in more exotic cases, maybe in the render loop of a game engine, or if you have huge data sets.但这仅在更奇特的情况下才重要,可能在游戏引擎的渲染循环中,或者如果您有大量数据集。 For most type of programs this is likely to be premature optimization (though one could argue creating the struct would make the code more readable, which would likely then be the main benefit).对于大多数类型的程序,这可能是过早的优化(尽管有人可能会争辩说创建结构会使代码更具可读性,这可能是主要的好处)。

Some useful reads:一些有用的读物:

If you want to store different type of objects on c# I recommend the use of ArrayList With ArrayList you can store any type of object since it is a dynamic collection of objects.如果您想在 c# 上存储不同类型的对象,我建议使用 ArrayList 和 ArrayList 您可以存储任何类型的 ZA8CFDE6331BD59EB662AC96 对象。

  ArrayList myAL = new ArrayList();
  myAL.Add("Hello");
  myAL.Add("World");
  myAL.Add("!");

You will need a using System.Collections;您将需要使用 System.Collections; To be abel to use this collection成为 abel 使用这个集合

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM