簡體   English   中英

如果類類型未知,如何創建類樣本數組並使用其方法

[英]How to create array of class exemplars and use their methods if type of class is unknown

我正在嘗試創建一個示例庫,並使用其方法。

public class PoolOfObjects
{
    public delegate Object InstanceCreation();
    public Object[] objects;
    bool?[] State;
    InstanceCreation _creator;
    Type _type;

    public PoolOfObjects(Type type, int objects_count, InstanceCreation creator)
    {
        objects = new object[objects_count];
        State = new bool?[objects_count];
        for (int i = 0; i < objects_count; i++)
            objects[i] = _creator;
    }

    //Must return an exemplar by state of object when called 
    public Object EjectObject (bool? state)
    {
        int i;
        for (i = 0; i < State.Length; i++)
            if (State[i] == state)
            { //create object if null
                if (objects[i] == null)
                    objects[i] = _creator;
                break;
            }
        return objects[i];
    }
}

這是一些類的示例,我必須在池中創建

public class Test
{
    public Test()
    {
        Console.WriteLine("constructor");
    }
    public void SomeMethod()
    {
        Console.WriteLine("SomeMethod");
    }
}

然后我嘗試像這樣使用它

PoolOfObjects pool = new PoolOfObjects(typeof(Test),27,delegate {
            return new Test();
        });
pool.EjectObject(null).SomeMethod();

但這還沒有看到一個方法,因為返回類型是對象。 我試圖將object []轉換為Type,但是卻收到“對象必須實現iconvertible”異常。

也許有一些簡單的方法可以像這樣初始化object[]

object = new (type)[object_count]

或者是其他東西?

感謝您的回答!

是的你可以。 您所預測的語法非常相似。

數組可以具有其包含的對象的類型:

T[] array = new T[size];

其中T是您想要數組保存的類型(類,結構)。 根據您的情況,代碼將是InstanceCreation

這將是為您解決C#Generics的好時機。 看一下System.Collections.Generic.List<T>

您確實可以將對象“投射”為特定類型。

object stringAsObject = "This is a string";
string stringAsString = (string)stringAsObject;

但是在這種情況下,我建議使用泛型。 在某些情況下,創建通用方法可能會有些復雜-幸運的是,我不認為這是其中之一。

使用泛型,您不必將所有內容都更改為“對象”,並且編譯器可以為您跟蹤類型。 這將允許它顯示您的代碼中存在的許多錯誤。

為了給您一個工作的起點,我在這里嘗試將您的對象池類更改為通用實現。 我為更改的內容和您仍需要處理的內容添加了注釋。 注意,我沒有運行它,只是檢查了Visual Studio中沒有突出顯示錯誤,因此一旦開始調試,可能仍然需要更改一些內容。 :)

// Changed to Generics. This makes the class easier to use.
public class PoolOfObjects<T>
{
    // Changed to private - you do not want this accessible from the outside
    // Changed the type to T so you do not have to cast.
    private T[] _objects;

    // Changed to prefix with _. 
    // Not all coding guidelines do this, but whatever you do be consistent.
    // Changed to states as there appears to be on per object.
    private bool?[] _states;

    // Using the standard Func<T> (function returning T)
    // instead of introducing a new delegate type
    private Func<T> _creator;

    // Changed to camelCase and Func<T> instead of custom delegate
    public PoolOfObjects(int objectsCount, Func<T> creator)
    {
        // Changed to remember the creator
        _creator = creator;
        // I left this an array, but consider changing to List<T>,
        // then the list can grow as needed. 
        _objects = new T[objectsCount];
        _states = new bool?[objectsCount];

        // removed initialization of objects
        // as it appears you do it when calling EjectObject
    }

    //Must return an exemplar by state of object when called 
    public T EjectObject(bool? state)
    {
        // TODO:
        // You never assign any values to the _states array,
        // so it will always have the value null.
        // this means if your method is called with true or false,
        // it will FAIL!
        // I do not know what "states" is for so I can't suggest how to fix it.

        // If it is to track if an object is already in use I recommend getting
        // rid of it and change your _objects to be:
        //   private Queue<T> _objects
        // Then this method will check if there are any items in the _objects queue,
        // if there is dequeue one and return it. If not, create a new object
        // and return it.
        // You then need to create another method to put the items back in the queue
        // after use.

        int i;
        for (i = 0; i < _states.Length; i++)
            if (_states[i] == state)
            { //create object if null
                if (_objects[i] == null)
                    // Changed to call your creator instead of assigning it.
                    _objects[i] = _creator();
                break;
            }
        // TODO: Your program will crash with an unclear error here if no object
        // has a state matching the requested state.
        return _objects[i];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM