C#如何编写通用方法

3

我该如何使这个方法通用?我该如何将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
你怎么知道 T 有一个 Stock_ID 属性? - John Wu
1
你必须对具有 Stock_ID 属性的某个类或接口添加约束到 T 上(这似乎不是泛型的最佳选择)。 - Rufus L
@JohnWu Stock_ID 是表示任何ID的符号。我在询问,在调用此方法时是否也可以设置Id属性? - Fk Bey
1
那么,在这种情况下,你怎么知道 T任何ID呢? - John Wu
1
在这种情况下,您需要一些方法来告诉编译器,您仅将此方法用于具有ID的表格上。否则,它无法知道,并且会假设您想要能够在任何类型上使用该方法。您可能需要添加一个接口和一个类型约束。 - John Wu
显示剩余2条评论
2个回答

5

通用约束要求您为泛型类型指定接口或父类。试试这个:

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

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

这种方法可以在你的方法中指定只按id排序。

GETLAST(x => x.StockId)

这回答了你如何在调用方法时传递id的问题。我认为你想要将这个包装器应用到表格中,通过id获取数据,但是你的表格具有不同命名的id,因此你不能只创建一个"IStock"接口。

但是使用这个方法,你可以拥有一个返回该表达式的接口,使你的表格实现该接口。这样你就有了一个通用接口,通用实现,并且表格可以给出不同命名的id。

尝试实现类似以下内容:

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

虽然有点别扭,但我认为这种方法应该能行。你可以尝试一些不同的方法,例如如果你控制了LocalSQL是如何创建的(比如通过工厂而不是直接在代码中),那么你可以在那里添加逻辑来正确构建LocalSQL对象,并给它正确的表达式(你有一个将类型映射到表达式的字典),这样就没有接口,你可以从静态上下文中访问它而无需初始化对象,而所有特定于LocalSQL和表映射的逻辑都在LocalSQL工厂中。


是的,这正是我想要的。但是我不理解TKey是什么意思。尽管添加了System.Linq.Expressions,Visual Studio仍然找不到TKey。 - Fk Bey
1
我已经尝试过了,更新了我的答案。Visual Studio没有报错。 - Erndob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接