Параметр типа C # читается только как базовый класс - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть базовый класс, который я назову TypeBase, и несколько классов, производных от него, для ухмылки давайте назовем их TypeImage и TypeAsset.Вот что происходит в коде:

...
TypeBase b = null;
MethodDoingStuff(passedID, ref b); 
RepositoryCall(b, otherArgs);

Итак, в MethodDoingStuff мы имеем что-то вроде этого:

public bool MethodDoingStuff (long passedID, ref TypeBase b)
{
     object concrete = DbCallThatGetsSubclass(passedID);//returns a subclass 
                              of TypeBase(in reality more than 2  possibilities)
     TypeBase tb = (TypeBase)concrete;
     b=tb;
     return true;
}

Итак, метод sig для вызова репозитория выглядит так:

  public virtual T FindByID<T>( T typeInstance, long id) where T : TypeBase
    {
        T item = (T)Activator.CreateInstance(typeof(T));

        using (IDbConnection cn = Connection)
        {
            item = cn.Get<T>(id);
        }

        return item;
    }

Проблема возникает в том, что cn.Get<T>(id) - это вызов Dapper Extension, Таблица, которую он ищет, основана на этом параметре типа, который, конечно, он видит как TypeBase.Соответствующие данные таблицы, конечно же, находятся в таблицах TypeImage или TypeAsset, или что-то еще.Моя свобода в основном заключается в репозитории: я могу изменить работу метода или ввести перегрузки.Я также могу изменить аргументы, передаваемые в MethodDoingStuff (), но по разным причинам не могу изменить сам метод.

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Вот что получилось: я сделал перегрузку для моего FindByID<T> метода, когда я передаю b.GetType.ToString(), и это дает правильный подкласс.В перегрузке я создаю экземпляр одного из них и использую отражение, чтобы передать его в качестве параметра типа в метод расширения Dapper.

 public virtual T FindByID<T>(T typeInstance, long id, string typeName) where T : TypeBase
    {
        Assembly asm = Assembly.GetCallingAssembly();
        var item = asm.CreateInstance(typeName);

        using (IDbConnection cn = Connection)
        {
            MethodInfo getInfo = typeof(SqlMapperExtensions).GetMethod("Get");
            MethodInfo getGeneric = getInfo.MakeGenericMethod(item.GetType());
            item = getGeneric.Invoke(cn, new object[] { cn,id,null,null });
        }

        return (T)item;
    }

Это работает, хотя я бы хотел избежать рефлексии, если бы мог.

0 голосов
/ 15 ноября 2018

Вы приводите тип к базовому классу. Поэтому, когда вы используете с Dapper, он видит TypeBase. Это проблема с наследованием. Использование интерфейса может помочь вам решить проблему.

...