简体   繁体   English

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

[英]is it possible to create anonymous type generics?

I've built a pagination class that works well for a specific data type, but now I need to make the type dynamic 我建立了一个分页类,该分页类对特定的数据类型非常有效,但是现在我需要使该类型动态

here is my code 这是我的代码

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

as you can see, this pagination class works only for 'Character', is it possible to create anonymous data type and invoke generic methods such as Skip and Take? 如您所见,此分页类仅适用于'Character',是否可以创建匿名数据类型并调用通用方法(例如Skip and Take)?

Yes, you can create the class as a generic class: 是的,您可以将类创建为通用类:

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

You just use generics for a base class and inherit, implementing the class. 您只需对基类使用泛型并继承并实现该类。

public class Pagination <T> where T : class

Then put T in all places you currently have the Character class 然后将T放在您当前拥有Character类的所有位置

this should be pretty simple... try this... 这应该很简单...尝试一下...

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

you might want to add a constraint on _type, like this (makes it so _type MUST be a class): 您可能想在_type上添加一个约束,像这样(使_type必须成为一个类):

public class Pagination< _type > where _type : class

This generic class should do the job. 这个通用类应该可以完成工作。

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

Yes, this is possible. 是的,这是可能的。 I would do it the following way: 我将通过以下方式进行操作:

  1. Hide the implementation, only expose an interface: 隐藏实现,只公开一个接口:

     public interface IPagination<T> { int PageSize { get; set; } int TotalPages { get; } IQueryable<T> GetPage(int page); } 
  2. Make the Pagination class generic and only an internal implementation (the outside only sees the interface) 使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. Offer an extension method to convert: 提供扩展方法来转换:

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

Sure it's possible but it's typically only useful within a method body. 当然可以,但是通常仅在方法体内有用。 For example 例如

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

This becomes problematic to pass between methods though because there is no way to state the name of an anonymous type hence nothing to put in for the T in IEnumerable<T> . 尽管由于无法声明匿名类型的名称,因此在方法之间进行传递变得很成问题,因此IEnumerable<T>T无需放入任何内容。 It's possible to do with generic tricks but it doesn't appear to fit what you need for this scenario 可以使用通用技巧,但似乎不适合您在这种情况下需要的技巧

Would this work for you? 这对您有用吗?

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

I'm not certain I see the correlation with anonymous types? 我不确定我是否看到与匿名类型的关联? Why do you need that to get this type to work for types other than Character ? 为什么要使此类型适用于Character以外的类型,您为什么需要它?

Have you tried this? 你有尝试过吗?

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

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

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