首页 > 解决方案 > 根据条件转换泛型

问题描述

我正在尝试返回派生类,但是对于某些实现,我必须提供更多设置,所以我有if,但是编译器不够聪明,无法知道一旦进入if,它应该能够转换TDerived1. 还有其他方法吗?

无法将类型“Derived1”转换为类型 T

public T GetData<T>(string name) where T : Data
{
    if (_cache.ContainsKey(name))
        return (T)_cache[name];

    using (var db = new LiteDatabase(_dbPath))
    {
        if (typeof(T) is ChartData)
        {
            var collection = db.GetCollection<ChartData>("Data");
            var chunksColl = db.GetCollection<ValuesChunk>(nameof(ValuesChunk));

            var data = collection.Include(d => d.Series).FindOne(Query.EQ(nameof(ChartData.Name), name));
            foreach (var series in data.Series)
            {
                for (int index = 0; index < series.Chunks.Count; index++)
                {
                    var chunk = chunksColl.FindById(series.Chunks[index].ChunkId);
                    series.ChangeChunk(index, chunk);
                }
            }

            _cache.Add(name, data);
            return (Data)data;
        }
        else
        {
            var collection = db.GetCollection<T>();
            return collection.FindOne(Query.EQ(nameof(ChartData.Name), name));
        }
    }
}

public abstract class Data {/*properties*/}
public class ChartData : Data {/*properties*/}
public class ScriptData : Data {/*properties*/}

标签: c#polymorphism

解决方案


上面的几个错误,这是有效的(它是否最好的设计是一个不同的问题):

public T Get<T>() where T : Base
{
    if (typeof(T) == typeof(Derived1)) //correction to this line
    {
        var derived = new Derived1();
        derived.Property1 = 5;
        return derived as T; //correction to this line
    }
    else
    {
        // return (T)myMethod;
    }

    return null;
}

或使用您编辑的版本:

public T GetData<T>(string name) where T : Data
{
    if (_cache.ContainsKey(name))
        return (T)_cache[name];

    using (var db = new LiteDatabase(_dbPath))
    {
        if (typeof(T) == typeof( ChartData)) //<======CORRECTION HERE
        {
            var collection = db.GetCollection<ChartData>("Data");
            var chunksColl = db.GetCollection<ValuesChunk>(nameof(ValuesChunk));

            var data = collection.Include(d => d.Series).FindOne(Query.EQ(nameof(ChartData.Name), name));
            foreach (var series in data.Series)
            {
                for (int index = 0; index < series.Chunks.Count; index++)
                {
                    var chunk = chunksColl.FindById(series.Chunks[index].ChunkId);
                    series.ChangeChunk(index, chunk);
                }
            }

            _cache.Add(name, data);
            return data as Data;//<======CORRECTION HERE
        }
        else
        {
            var collection = db.GetCollection<T>();
            return collection.FindOne(Query.EQ(nameof(ChartData.Name), name));
        }
    }
}

推荐阅读