[英]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.