简体   繁体   English

C#在类中创建对象

[英]C# Creating an object within a class

I'm making a map loading system that uses chunks so that the entire map data doesn't have to be loaded at once. 我正在制作一个使用块的地图加载系统,这样就不必一次加载整个地图数据。

I have a "World" class, and within that class I'm creating an instance of a class called "ChunkManager". 我有一个“世界”类,在该类中,我正在创建一个名为“ ChunkManager”的类的实例。

I'm unsure if creating an instance inside another class is a good idea/considered a "normal" thing to do etc. I've not been able to find anything about this while searching the internet. 我不确定在另一个类中创建实例是否是一个好主意/认为是“正常”的事情等等。在搜索互联网时,我无法找到任何关于此的信息。

So my question is: Should I be creating an instance of a class within a class in the way I have, or will there be problems with doing it this way? 所以我的问题是:是否应该按照自己的方式在一个类中创建一个类的实例,或者这样做会不会有问题?

Here is my code, if it's relevant: 如果相关,这是我的代码:

class World
{

    public string WorldName { get; set; }
    ChunkManager chunkManager = new ChunkManager();


    public World(string worldName)
    {
        WorldName = worldName;

    }

    public void AddChunk(int X, int Y)
    {
        //Plus other validation code here that I didn't paste
        chunkManager.AddChunk(X, Y);
    }
}

And ChunkManager: 和ChunkManager:

class ChunkManager
{
    public int TotalGeneratedChunks { get; private set; }

    private List<Chunk> ChunkList = new List<Chunk>();

    public bool CheckIDExists(int IDToCheck)
    {
        foreach (Chunk i in ChunkList)
        {
            if (i.UniqueID == IDToCheck)
            {
                return true;
            }
        }

        return false;
    }

    public void AddChunk(int X, int Y)
    {
        ChunkList.Add(new Chunk(TotalGeneratedChunks++, X, Y));

    }
}

Your code is fine BUT if either class grows to be more complex and you want to be able to test them independently you should instead define an interface IChunkmanager and inject an instance of ChunkManager into World: 如果任何一个类变得越来越复杂,并且您希望能够独立测试它们,那么您的代码就可以了,但是您应该定义一个接口IChunkmanager并将ChunkManager的一个实例注入World:

class World
{

    public string WorldName { get; set; }
    private readonly IChunkManager chunkManager;


    public World(string worldName, IChunkManager chunkmanager)
    {
        this.chunkManager = chunkManager;
        ...

With this approach you can use a mocking framework to inject a mock IChunkManager and can test the World class independently. 使用这种方法,您可以使用模拟框架来注入模拟IChunkManager并可以独立测试World类。

In general classes should be loosely coupled. 一般而言,课程应松散耦合。 As soon as you new-up an instance of another class within a class you have tightly-bound them in a way that makes it hard to test them independently (or to reuse them in different situations). 一旦在一个类中更新了另一个类的实例,您就将它们紧密地绑定在一起,从而很难独立测试它们(或在不同情况下重用它们)。

It's perfectly fine to create an instance of a class inside another. 在另一个内部创建一个类的实例非常好。 chunkManager is what is known as a field and the syntax for initializing it inline along with its declaration is called an initializer . chunkManager是所谓的field ,用于将其内联初始化及其声明的语法称为initializer You can find more information on initializers and how they are different from initializing via the constructor in this blog series by Eric Lippert 您可以在Eric Lippert的本系列博客中找到有关初始化器的更多信息,以及它们与通过构造函数进行初始化的区别。

Part 1 Part 2 第1 部分第2部分

It might some times be a better idea to initialize fields via the constructor though as this lets you use dependency injection (parameter injection to be precise) which can greatly improve the testability and modularity of your code. 通过构造函数初始化字段有时可能是一个更好的主意,尽管这使您可以使用依赖项注入(准确地说是参数注入),这可以大大提高代码的可测试性和模块化。 If you're interested in learning more about dependency injection I suggest purchasing and reading this book. 如果您想了解更多关于依赖注入,我建议购买和阅读本书。

标准做法是在构造函数内部设置值,因为它允许依赖项注入并使修改构造函数以使用参数变得轻而易举。

If you are going to create a lot of World, i suggest creating an Abstract base that implements the ChunckManager. 如果要创建很多World,我建议创建一个实现ChunckManager的Abstract基础。

That way you can leverage the use of base class, promote code reuse. 这样,您可以利用基类的使用,促进代码重用。 You can also make your ChunkManager singleton since it only needs to be used by the base, and then use a method to actually instantiate the ChunkManager if you need specific properties from maps. 您还可以使ChunkManager单例,因为它只需要由基础使用,然后,如果您需要地图中的特定属性,则可以使用一种方法来实例化ChunkManager。

Use DI to pass the prop from child to base to instantiation of the ChunkManager 使用DI将道具从子级传递到基础到ChunkManager的实例化

是的,您可以在另一个类中使用一个类类型,就像在该类中使用的类型一样,例如当您使用字符串a = new string()时,使用类字符串的对象及其常规代码

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

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