【问题标题】:Pass typed array into generic function?将类型化数组传递给泛型函数?
【发布时间】:2012-04-16 11:55:23
【问题描述】:

我有一个集合IQueryable<Car>,我想将它传递给一个泛型函数,该函数将IQueryable<T> 作为参数接收,类似于(位于基类中)。

public abstract class  BaseController<T> : ControllerBase  where T : BaseObj, new()
{
    public IQueryable<T> FilterEntities(IQueryable<T> entities)
    {
    }
}

传递这个的正确方法是什么?投掷?安全演员?

【问题讨论】:

  • 这个方法是在泛型类中定义的吗?因为你的方法不是通用的,所以它没有定义任何类型参数
  • 这取决于你想用它做什么......
  • 如果你只传递IQueryable&lt;Car&gt; 的实例,你为什么要让这个方法通用?
  • 不确定你想用BaseController做什么,但如果可能的话,我会尽量避免使用它们。例如,如果您想在项目中使用普通控制器、Web api 控制器和异步控制器,则需要创建三个基本控制器并复制一些代码。相反,您应该查看全局或控制器级别的过滤器。

标签: c# generics collections


【解决方案1】:

你的问题是你的方法不是通用的,类是。请注意,在方法名称之后没有 &lt;T&gt;,这意味着您必须传入一个 IQueryable,该 IQueryable 是您为该类的类型参数使用的内容。

例如,如果对象是这样实例化的:

new BaseController<BaseObject>(..) //ignoring that BaseController is abstract

您需要传递IQueryable&lt;BaseObject&gt;,因此在您希望传递IQueryable&lt;Car&gt; 的情况下,控制器类型需要从BaseController&lt;Car&gt; 派生

另一方面,如果您希望方法是通用的,请将方法的签名更改为

public IQueryable<TElement> FilterEntities<TElement>
            (IQueryable<TElement> entities)

不包括 T 上的类型约束,你对类的类型参数有。如果应该对通用方法强制执行此操作,则签名需要:

public IQueryable<TElement> FilterEntities<TElement>(IQueryable<TElement> entities) 
            where TElement : BaseObj, new()

编辑 如果您希望有一个仅使用 T 作为类型参数的“默认”方法,则必须将其实现为非泛型方法,就像您在代码中使用的那样,该类将是:

  public abstract class  BaseController<T> : ControllerBase  
                where T : BaseObj, new()
  {

     public IQueryable<T> FilterEntities(IQueryable<T> entities)
     {
            return FilterEntities<T>(entities);
     }

     public IQueryable<TElement> FilterEntities<TElement>(IQueryable<TElement> entities) 
                where TElement : BaseObj, new()
  }

【讨论】:

  • 反正有类泛型和方法泛型,因为大多数时候我希望方法使用类中的 T 但有时我想重用相同的代码传入与类不同的类型 T ?我收到警告。 ."类型参数与外部类型名称同名.."
  • @leora 你必须为此编写一些样板代码
【解决方案2】:
public IQueryable<TQueryable> FilterEntities<TQueryable>(
    IQueryable<TQueryable> entities)
{
}

您需要使该方法成为泛型方法(括号前的函数名称后的 告诉编译器该方法是泛型的)。

方法的类型参数TQueryable与类类型不同。如果你不想要它到你的方法签名应该没问题。

【讨论】:

  • 并且你应该选择一个不同于类的类型参数名称
  • @Rune FS - 如果我选择相同的名称“类型参数名称与外部类型相同”,我会收到警告。 .这是一个问题吗,因为如果可能的话,我想以两种方式使用该方法。 .
  • @leora 类中的类型参数将被方法中的类型参数覆盖(即在方法的签名和实现中 T 因为它指的是用于类的类型是无法访问,它不能解决您正在寻找的“默认类型”
【解决方案3】:

如下定义FilterEntities

public IQueryable<T> FilterEntities<T>(IQueryable<T> entities)
{
}

现在你可以通过如下方式传递 IQueryable

    IQueryable<Car> x = null; //Initialize it
    FilterEntities<Car>(x);

【讨论】:

    猜你喜欢
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多