简体   繁体   English

C#泛型和推断类型

[英]C# Generics and inferring type

I'm struggling while trying to write generic methods to save and load data from a Sterling database. 我在努力编写通用方法来保存和加载Sterling数据库中的数据时遇到了困难。

This is my save method: 这是我的保存方法:

public static void SaveList<T>(List<T> listToSave)
{
    foreach (T listItem in listToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

I get squiggly red line under save and an error of "The Type T must be a reference type in order to use it as parameter T" 我在保存下出现了波浪形的红线,并且出现“类型T必须是参考类型才能将其用作参数T”的错误

This is my load method: 这是我的加载方法:

    public static List<T> LoadList<T>()
    {
        List<T> list = (from index in DatabaseInstance.Query<T, int>() select index.Key).ToList();

        return list;
    }

I get the same error. 我犯了同样的错误。

Any ideas? 有任何想法吗?

Cheers 干杯

Steve 史蒂夫

UPDATE: 更新:

I added a where T : class as suggested and got an error: 我按照建议添加了一个T:class,并收到错误:

The Type T must have a public parameterless constructor in order to use it as a parameter Type T必须具有公共无参数构造函数才能将其用作参数

Following instructions in the link provided by Bryan I added , new() on the end and all working now. 按照Bryan提供的链接中的说明添加,new()结束,现在全部工作。

You need a generic type constraint on your definition: 您的定义需要泛型类型约束

public static void SaveList<T>(List<T> listToSave) where T : class
{
    foreach (T listItem in listToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

public static List<T> LoadList<T>()  where T : class
{
    List<T> list = (from index in DatabaseInstance.Query<T, int>() select index.Key).ToList();
    return list;
}

To fix your code, you need a generic constraint that forces a reference type, as shown below. 要修复代码,您需要一个强制引用类型的通用约束,如下所示。 To set this answer out from others already posted, I also recommend that you use IEnumerable<T> rather than List<T>: 要从已发布的其他人中设置此答案,我还建议您使用IEnumerable <T>而不是List <T>:

public static void SaveList<T>(IEnumerable<T> itemsToSave) where T : class
{
    foreach (T item in itemsToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

public static IEnumerable<T> LoadList<T>() where T : class
{
    return (from index in DatabaseInstance.Query<T, int>()
            select index.Key);
}

The change to IEnumerable<T> should be compatible with all your existing code, as List<T> already implements IEnumerable<T>. 对IEnumerable <T>的更改应该与所有现有代码兼容,因为List <T>已经实现了IEnumerable <T>。 Used properly, this will also allow you get a nice performance boost by keeping fewer items at a time in RAM and make your code more powerful by allowing it to work with other collection types. 如果使用得当,这也可以让你通过在RAM中一次保留更少的项目来获得良好的性能提升,并通过允许它与其他集合类型一起使用来使代码更强大。

The problem is that, in your existing code, T can be anything. 问题是,在您现有的代码中,T可以是任何东西。 That's not OK because the Save function only accepts reference types. 这不好,因为Save函数只接受引用类型。

You need to place a constraint which effectively makes a commitment to the compiler that T will be a reference type. 您需要设置一个约束 ,该约束有效地使编译器承诺T将成为引用类型。

public static void SaveList<T>(List<T> listToSave) where T : class
{
    foreach (T listItem in listToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

can you try? 你能试一下吗?

public static void SaveList<T>(List<T> listToSave) where T:class
{
    foreach (T listItem in listToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

Try adding a class constraint: 尝试添加class约束:

public static void SaveList<T>(List<T> listToSave) where T : class
{
    foreach (T listItem in listToSave)
    {
        DatabaseInstance.Save(listItem);
    }
}

public static List<T> LoadList<T>() where T : class
{
    List<T> list = (from index in DatabaseInstance.Query<T, int>()
            select index.Key).ToList();

    return list;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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