【问题标题】:How do we create c# method to accept different types of parameter我们如何创建 c# 方法来接受不同类型的参数
【发布时间】:2016-04-07 23:33:17
【问题描述】:

我是 asp.net 的新手,并使用实体框架创建了一个 MVC 项目。大多数情况下它按我的预期工作,但有一个问题,我需要将参数传递给可能是不同类型的方法。我需要这个,因为我不想在每个发送相同结果的类中编写相同的方法。这是我的设置

public class BaseQuery : IOSSQuery
{
    private Entities dbcontext;

    public BaseQuery() : this(new Entities())
    {
    }
    public BaseQuery(Entities context)
    {
        this.dbcontext = context;
    }
    public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
        return SimpleItemList;
    }
    public virtual List<SimpleItem> GetAllItems(Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        return SimpleItemList;
    }
}

然后我有一个查询类,

public class ColorQuery : BaseQuery
{
    public override List<SimpleItem> GetAllItems(Int32 skip)
    {
        return GetAllItemsFromQuery( dbcontext.tbl_color, skip)
    }
}

界面如下

public interface IOSSQuery : IDisposable
{
    List<SimpleItem> GetAllItems(Int32 skip);
}

我想从我的控制器调用方法如下

public JsonResult Color(String range)
{
   ColorQuery query = new ColorQuery();
   List<string> ranges = range.Split(',').ToList<string>();
   var SimplePage = getAllItems(query, Convert.ToInt32(ranges[0]));
   return Json(SimplePage, JsonRequestBehavior.AllowGet);
}

public PagedData<SimpleItem> getAllItems( IOSSQuery queryObject,  int range )
{
   var SimplePage = new PagedData<SimpleItem>();
   SimplePage.total = queryObject.TotalItems();
   SimplePage.data = queryObject.GetAllItems(range);
   return SimplePage;
}

此代码在 BaseQuery 类的这一行抛出错误

public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)

Error   CS1061  'T' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)

不知道如何在方法中传递不同的类型。我尝试了Method to accept different types 的解决方案,但没有运气。任何人都可以阐明这一点。谢谢你的时间。

编辑: 这就是它在我的实体中的设置方式

public DbSet<tbl_Category> tbl_Category { get; set; }
public DbSet<tbl_color> tbl_color { get; set; }

编辑 2:

我有多个不同列的表。我的想法是对所有返回相同结果的表使用“BaseQuery”中的通用方法,如果我需要,仍然希望使用“ColorQuery”或对不同的查询说“CategroyQuery”类。

【问题讨论】:

  • 为什么在你的类“ColorQuery”中实现“IOSSQuery”,“BaseQuery”已经实现了?
  • 哎呀删除了。虽然不能解决问题:)

标签: c# asp.net


【解决方案1】:

为什么不尝试使用 IQueryable 参数而不是通用类型参数?

public List<SimpleItem> GetAllItemsFromQuery(IQueryable table,Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
        return SimpleItemList;
    }

【讨论】:

  • 不起作用,同样的错误“IQueryable”不包含“Where”的定义,并且找不到接受“IQueryable”类型的第一个参数的扩展方法“Where”(您是否缺少using 指令还是程序集引用?)
【解决方案2】:

当您使GetAllItemsFromQuery 方法成为通用方法(使用T 作为参数类型)时,编译器不再知道它在参数table 中接收的对象类型 - 所以当您调用像IsActiveWhere 之类的扩展方法,编译器无法将它们绑定到具体实现;实际上,它无法判断您传入的对象是否甚至 /has/ 那些成员。 您可以在方法声明中使用 where 子句向编译器提供有关其可以预期的类型的更多信息:

public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)
    where T: IEnumerable<IEntity>
{
    List<SimpleItem> SimpleItemList = new List<SimpleItem>();
    SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
    return SimpleItemList;
}

假设您的所有实体类型都实现了IEntity,这将是一个包括IdNameIsActive 等的接口。

如果我们能看到 Entities 类型的代码,给你一个具体的答案会更容易,但就你想要做的事情而言,where 子句是要走的路。

【讨论】:

  • 其设置为公共 DbSet tbl_color { get;放; } 在实体类中
【解决方案3】:

您的T table 似乎应该被限制为IEnumerable&lt;T&gt;,因为您像IEnumerable&lt;T&gt; 一样使用它:

SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();

尝试使用where(使用System.Linq)声明它:

public List<SimpleItem> GetAllItemsFromQuery<T, U>(T table,Int32 skip) where T : System.Collections.IEnumerable<U>

或者简单地说:

public List<SimpleItem> GetAllItemsFromQuery<T>(IEnumerable<T> table,Int32 skip)

【讨论】:

  • T 不能是 IEnumerable&lt;T&gt;,否则类型将是自身的枚举。你的意思是T: IEnumerable&lt;U&gt; 代表GetAllItemsFromQuery&lt;T, U&gt;,还是简单地说GetAllItemsFromQuery&lt;T&gt;(IEnumerable&lt;T&gt; table,Int32 skip)
【解决方案4】:

您可以使用函数名重载。没关系。

【讨论】:

    【解决方案5】:

    萨默,

    您的代码中的问题是您使用的是泛型类型参数,正如@FacticiusVir 所说,编译器无法知道哪种类型是,但同时您希望此类型具有 Id 属性, Name 属性和 IsActive 属性。

    所以你可以做两件事:

    1. 使 GetAllItemsFromQuery 方法更具体,类似这样:
    
            public List GetAllItemsFromQuery(IEnumerable table, Int32 skip)
            {
                List SimpleItemList = new List();
                SimpleItemList = table.Where(p => p.IsActive).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
                return SimpleItemList;
            }
    
    1. 通过限制使其具有通用性,并使用前面提到的三个属性为您的实体创建一个基类:

      public class tbl_color: BaseEntity
      {
      
      }
      
      public class BaseEntity
      {
          public bool IsActive { get; set; }
          public string Name { get; set; }
          public int Id { get; set; }
      }
      
      public List<SimpleItem> GetAllItemsFromQuery<T>(IEnumerable<T> table, Int32 skip) where T : BaseEntity
      {
          List<SimpleItem> SimpleItemList = new List<SimpleItem>();
          SimpleItemList = table.Where(p => p.IsActive).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
          return SimpleItemList;
      }
      

    【讨论】:

    • Sammer,IEnumerable 接口的扩展方法 Where 是什么,请确保您已添加 System.Linq 命名空间。
    • 哦,对了,所以我必须编辑我所有的实体类定义来添加一个接口。那是痛苦。
    猜你喜欢
    • 2012-06-18
    • 2013-07-14
    • 2011-10-20
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 2022-06-23
    相关资源
    最近更新 更多