C# как сделать универсальный c метод - PullRequest
3 голосов
/ 28 апреля 2020

как я могу сделать этот метод обобщенным c? Как мне отразить Stock_ID для этого метода? Заранее спасибо

public class LocalSQL<T> where T : new() 
{
    public static async Task<List<T>> GETLAST( )
    {                    
        return await conn.Table<T>()
            .OrderByDescending(x => x.Stock_ID)
            .Take(10)
            .ToListAsync();
    }
}

Ответы [ 2 ]

5 голосов
/ 28 апреля 2020
public class LocalSQL<T> where T : new() 
{
    public static async Task<List<T>> GETLAST(Expression<Func<T, TKey>> key)
    {                    
        return await conn.Table<T>()
            .OrderByDescending(key)
            .Take(10)
            .ToListAsync();
    }
}

Таким образом, вы можете указать только идентификатор для заказа в вашем методе.

GETLAST (x => x.StockId)

Это ответ на ваш вопрос о том, как пройти идентификатор при вызове метода. Я думаю, что вы хотите, чтобы эта оболочка поверх таблиц использовалась для идентификации по идентификатору, но ваши таблицы имеют идентификаторы с разными именами, поэтому вы не можете просто создать один интерфейс «IStock».

Но используя это, вы можете иметь интерфейс, который вместо этого возвращает это выражение и заставляет ваши таблицы реализовывать интерфейс. Таким образом, у вас есть универсальный c интерфейс, универсальная c реализация, и таблицы могут дать вам идентификаторы с разными именами.

Пробная реализация, что-то вроде этого:

public class StockTable : IWithId<StockTable>
{
    public long Stock_Id { get; set; }

    public Expression<Func<StockTable, long>> IdExpression => x => x.Stock_Id;
}

public interface IWithId<T>
{
    Expression<Func<T, long>> IdExpression { get; }
}

public class LocalSQL<T> where T : IWithId<T>, new()
{
    public static async Task<List<T>> GETLAST()
    {
        var obj = new T();

        return await conn.Table<T>()
            .OrderByDescending(obj.IdExpression)
            .Take(10)
            .ToList();
    }
}

Такое чувство немного неловко, но я думаю, что-то вроде этого должно работать. Вы можете попробовать несколько разных подходов, например, если вы контролируете, как создается Local SQL (как через фабрику, а не напрямую в коде), у вас может быть logi c, который корректно создает объект Local SQL, и дает ему правильное выражение (у вас есть словарь типов, сопоставляемых с выражением), таким образом, нет интерфейсов, вы можете получить к нему доступ из контекста stati c, не инициируя объект, и все логи c Speci * 1021. * to Local SQL, и сопоставления таблиц будут на фабрике Local SQL.

5 голосов
/ 28 апреля 2020

Ограничения generi c требуют указания интерфейса или родительского класса для типа generi c. Попробуйте это

public interface IStock
{
    long Stock_ID { get; set; }
}


public class LocalSQL<T> where T : IStock, new()
{
    public static async Task<List<T>> GETLAST( )
    {                    
        return await conn.Table<T>()
            .OrderByDescending(x => x.Stock_ID)
            .Take(10)
            .ToListAsync();
    }
}
...