是否可以创建匿名类型泛型

本文关键字:类型 泛型 创建 是否 | 更新日期: 2023-09-27 17:49:15

我已经构建了一个分页类,它适用于特定的数据类型,但是现在我需要将类型设置为dynamic

这是我的代码

public class Pagination {
    public IQueryable<Character> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages {
        get {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<Character> items, int pageSize) {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<Character> GetPage(int pageNumber) {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}

正如你所看到的,这个分页类只适用于'Character',是否有可能创建匿名数据类型并调用通用方法,如Skip和Take?

是否可以创建匿名类型泛型

是的,您可以将该类创建为泛型类:

public class Pagination<T> {
    public IQueryable<T> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages {
        get {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<T> items, int pageSize) {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<T> GetPage(int pageNumber) {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}

您只需为基类使用泛型并继承,实现该类。

public class Pagination <T> where T : class

然后在所有当前有字符类

的地方加上T

这应该很简单…试试这个…

public class Pagination<_type> 
{
    public IQueryable<_type> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages {
        get {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<_type> items, int pageSize) {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<_type> GetPage(int pageNumber) {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}

你可能想在_type上添加一个约束,像这样(使得_type必须是一个类):

public class Pagination< _type > where _type : class

是的,这是可能的。我将这样做:

  1. 隐藏实现,只暴露一个接口:

    public interface IPagination<T>
    {
        int PageSize { get; set; }
        int TotalPages { get; }
        IQueryable<T> GetPage(int page);
    }
    
  2. 使Pagination类泛型且仅作为内部实现(外部只能看到接口)

    public class Pagination<T> : IPagination<T> {
        public IQueryable<T> Items { get; set; }
        public int PageSize { get; set; }
        public int TotalPages {
            get {
                        if (this.Items.Count() % this.PageSize == 0)
                        return this.Items.Count() / this.PageSize;
                    else
                        return (this.Items.Count() / this.PageSize) + 1;
                }
            }
            internal Pagination(IQueryable<T> items, int pageSize) {
                this.PageSize = pageSize;
                this.Items = items;
            }
            public IQueryable<T> GetPage(int pageNumber) {
                pageNumber = pageNumber - 1;
                return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
            }
    }
    
  3. 提供一个扩展方法来转换:

     public static IPagination<T> AsPagination (this IQueryable<T> source, int pageSize)
     {
         if(source == null)
             throw new ArgumentNullException("source");
         return new Pagination<T>(source, pageSize);
     }
    

这个泛型类应该可以完成这项工作。

public class Pagination<T>
{
    public IQueryable<T> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages
    {
        get
        {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<T> items, int pageSize)
    {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<T> GetPage(int pageNumber)
    {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}

当然这是可能的,但它通常只在方法体中有用。例如

var array = new[] {
  new { Name = "Jared", Age = 30 },
  new { Name = "Bob", Age = 21 }
};
var query = array.Skip(1).Take(1);

这在方法之间传递变得有问题,因为没有办法声明匿名类型的名称,因此在IEnumerable<T>中没有为T放入任何东西。可以使用一般的技巧,但它似乎不适合这种情况

这对你有用吗?

public class Pagination<T> {
    public IQueryable<T> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages {
        get {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<T> items, int pageSize) {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<T> GetPage(int pageNumber) {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}

我不确定我看到了匿名类型的相关性?为什么需要这样才能使该类型适用于Character以外的类型?

你试过吗?

public class Pagination<T> where T : class
{
    public IQueryable<T> Items { get; set; }
    public int PageSize { get; set; }
    public int TotalPages {
        get {
            if (this.Items.Count() % this.PageSize == 0)
                return this.Items.Count() / this.PageSize;
            else
                return (this.Items.Count() / this.PageSize) + 1;
        }
    }
    public Pagination(IQueryable<T> items, int pageSize) {
        this.PageSize = pageSize;
        this.Items = items;
    }
    public IQueryable<T> GetPage(int pageNumber) {
        pageNumber = pageNumber - 1;
        return this.Items.Skip(this.PageSize * pageNumber).Take(this.PageSize);
    }
}