简体   繁体   中英

C# how to make generic method

how can i make this method generic? How should i reflect the Stock_ID to this method?Thanks in Advance

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();
    }
}

The generic constraints require you to specify the interface or parent class for the generic type. Try this

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();
    }
}
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();
    }
}

This way you can specify only the id to order by in your method.

GETLAST(x => x.StockId)

This answers your question on how to pass an id when calling a method. What I think you want is to have this wrapper over tables to get things by id but your tables have differently named id's so you can't just make one "IStock" interface.

But using this, you can have an interface that returns that expression instead, and make your tables implement the interface. This way you have a generic interface, generic implementation, and tables can give you differently named id's.

Tried implementing, something like this:

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();
    }
}

It feels a bit awkward, but I think something like this should work. You can try some different approaches, eg if you control how LocalSQL is created(as in through a factory and not directly in the code), you could have logic there that correctly builds LocalSQL object, and gives it the correct expression(you have a dictionary of types mapping to expression), this way there's no interfaces, you can access it from a static context without initiating an object, and all of the logic specific to LocalSQL and table mappings would be in the LocalSQL factory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM