簡體   English   中英

通用 Class 加載程序:“T”必須是具有公共無參數構造函數的非抽象類型

[英]Generic Class Loader: 'T' must be a non-abstract type with a public parameterless constructor

我有許多類似的類,我正在嘗試創建一個通用方法來加載每個 class 的對象列表。 我沒有使用任何 ORM,而是使用相應的 SQL 查詢加載 SqlDataReader。

我嘗試過使用接口並使用 generics。

我僅使用 2 個短類簡化了以下問題:

界面:

public interface IMyEntity<T> where T : new()
{
    public List<T> ConvertToObjects(SqlDataReader dr);

    public static IMyEntity<T> CreateInstance() 
    {
        return null;
    }
}

Class 1:

public class Cat : IMyEntity<Cat>
{   
    public long CatID { get; set; } 
    public string CatName { get; set; } 
    public int OwnerID { get; set; }

    public List<Cat> ConvertToObjects(SqlDataReader dr)
    {
        List<Cat> cats = new();
        if (dr.HasRows)
        {
            while (dr.Read())
            {
                Cat cat = new()
                {
                    CatID = dr.GetInt32("CatID"),
                    CatName = dr.GetString("CatName"),
                    OwnerID = dr.GetInt32("OwnerID")
                };
                cats.Add(cat);
            }
            dr.Close();
        }
        return cats;
    }

    public IMyEntity<Cat> CreateInstance()
    {
        IMyEntity<Cat> cat = new Cat();
        return cat;
    }
}

Class 2:

public class Dog : IMyEntity<Dog>
{
    public long DogID { get; set; }
    public string DogName { get; set; }
    public int Age { get; set; }

    public List<Dog> ConvertToObjects(SqlDataReader dr)
    {
        List<Dog> dogs = new();
        if (dr.HasRows)
        {
            while (dr.Read())
            {
                Dog dog = new()
                {
                    DogID = dr.GetInt32("DogID"),
                    DogName = dr.GetString("DogName"),
                    OwnerID = dr.GetInt32("Age")
                };
                dogs.Add(dog);
            }
            dr.Close();
        }
        return dogs;
    }

    public IMyEntity<Dog> CreateInstance()
    {
        IMyEntity<Dog> dog = new Dog();
        return dog;
    }
}

我有另一個 class 使用這種方法:

public async Task<IEnumerable<T>> GetObjectAsync<T>(string procedureName)
{
    if (_connection.State != ConnectionState.Open) _connection.Open();
    SqlCommand command = new(procedureName, _connection);
    SqlDataReader dr = await cmd.ExecuteReaderAsync().ConfigureAwait(false);

    var myEntity = IMyEntity<T>.CreateInstance();
    IEnumerable<T> objs = myEntity.ConvertToObjects(dr);

    return objs;
}

'CreateInstance' 行返回以下錯誤:“'T' 必須是具有公共無參數構造函數的非抽象類型,才能將其用作泛型類型或方法 'IMyEntity' 中的參數 'T'”

調用方法自己的泛型類型中缺少T: new()約束。

public async Task<IEnumerable<T>> GetObjectAsync<T>(string procedureName)

因此,編譯器無法保證滿足IMyEntity<T>中接口的約束要求。 它與任何特定的方法調用無關,限制要求來自接口定義本身。

public interface IMyEntity<T> where T : new()

要么從接口中刪除限制——在這種情況下不能使用new T() ——要么將限制添加到調用方法的泛型類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM