在 C# 中使用原始类型?

Using raw types in C#?

提问人:V.Lap 提问时间:9/3/2021 最后编辑:V.Lap 更新时间:9/3/2021 访问量:296

问:

我可以像 Java 一样在 C# 中使用原始类型吗,或者有解决方法吗?我知道在 Java 中使用原始类型是一种不好的做法,但这可以解决我目前的问题。 我有一个对象,它有一个包含池的字段,因此它可以在完成工作时返回到该池。

    //C#
    public class MyObject : IPoolable
    {
        public Pool<MyObject> pool;
    }

但是如果有一种新的对象(例如:),我希望我的领域没有。(派生自 or 的对象也有很多种)。 在 Java 中,我可以将字段定义为原始类型,这样就不会出现编译错误。MovableObjectpoolPool<MovableObject>Pool<MyObject>MovableObjectMyObjectpoolPool

    //Java
    public class MyObject implements IPoolable
    {
        public Pool pool;
    }

我正在使用一种方法来返回两个版本中的所有类型的对象。在 Java 中,它运行良好,但在 C# 中,它有编译错误。

    //Java
    static public <T extends MyObject> T createObject(Class<T> type) {
        Pool<T> pool = Pools.get(type);
        T obj= pool.obtain();
        obj.setPool(pool); //This won't have any problem since it is raw type
        return obj;
    }
    //C#
    public static T CreateObject<T>() where T : MyObject
    {
        Pool<T> pool = Pools.GetPool<T>();
        T obj= pool.Obtain();
        obj.Pool = pool; //Error: cannot convert Pool<T> to Pool<MyAction>
        return obj;
    }

编辑1:提供其他类和最小的可重现示例

public interface IPoolable
{
    void Reset();
}
public abstract class Pool<T> where T : IPoolable
{
    private readonly Stack<T> freeObjects = new Stack<T>();

    public Pool() { }

    protected abstract T InstantiateObject(object[] args);

    public T Obtain(object[] args = null)
    {
        return freeObjects.Count == 0 ? InstantiateObject(args) : freeObjects.Pop();
    }
    public void Free(T obj)
    {
        if (obj != null)
        {
            freeObjects.Push(obj);
            Reset(obj);
        }
    }
    protected virtual void Reset(T obj)
    {
        obj.Reset();
    }
    public void Clear()
    {
        freeObjects.Clear();
    }
}

//ReflectionPool
public class ReflectionPool<T> : Pool<T> where T : IPoolable
{
    public ReflectionPool() : base()
    {
    }

    protected override T InstantiateObject(object[] args)
    {
        return (T)Activator.CreateInstance(typeof(T), args);
    }

}
public class Pools
{
    static private readonly Dictionary<Type, object> typePools = new Dictionary<Type, object>();

    static public Pool<T> GetPool<T>(int max) where T : IPoolable
    {
        Type type = typeof(T);
        if (!typePools.TryGetValue(type, out object pool))
        {
            pool = new ReflectionPool<T>();
            typePools.Add(type, pool);
        }
        return (Pool<T>)pool;
    }

    static public Pool<T> GetPool<T>() where T : IPoolable
    {
        return GetPool<T>(100);
    }
}

所以在类中,有一个方法让我的对象做某事,完成后,需要将当前对象返回到 Pool 中MyObject

//Base Object
public abstract class MyObject : IPoolable
{
    public Pool<MyObject> pool; //This is still a problem
    public void CallMe()
    {
        if (Act()) //If this object completing acting
        {
            ToPool();
        }
    }
    public abstract bool Act();
    public void ToPool()
    {
        pool.Free(this);
        pool = null;
    }

    public abstract void Reset();
}

//Movable Object
public class MovableObject : MyObject
{
    //public Pool<MyObject> pool; //Put this here as comment because I want it become Pool<MovableObject>
    public override bool Act()
    {
        return true; //Return false if not reach destination
    }

    public override void Reset() { }

    public override string ToString()
    {
        return "Movable";
    }
}
//I'm using this class for create object I want
public class ObjectFactory
{
    public static T CreateObject<T>() where T : MyObject 
    {
        Pool<T> pool = Pools.GetPool<T>();
        if(pool != null)
        {
            T obj = pool.Obtain();
            obj.pool = pool; //Error here: Cannot implicitly convert type 'Pool<T>' to 'Pool<MyObject>'
            return obj;
        }
        return null;
    }

    public static MovableObject MovableObject()
    {
        return CreateObject<MovableObject>();
    }
}

编辑 2:重新更新了编辑 1 中的代码

C# 泛型继承 原始 类型

评论


答: 暂无答案