【问题标题】:Why does my generic <T> is not Resolved?为什么我的通用 <T> 没有解决?
【发布时间】:2013-09-08 13:06:27
【问题描述】:

我有一堂电影课:

internal class Movie
    {
        public string Name { get; set; }
        public string Year { get; set; }
    }

我有这个代码:

 var Movies = CreateMovies(); //IEnumerable<Movie>
 var sorter = new Sorter<Movie>();
 sorter.AddSort(Movies,  m => m.Year , a=>a.Name ,.....as many as I want....);

这里是Sorter 类:

 class Sorter<T>
{
    public void AddSort(IEnumerable<T> movs,  params Expression<Func<T, object>>[]    funcs)
    {
                 /*...*/ 
        movs.OrderBy(d=>d.); //<----- here is the problem : where is the columns ?
    }
}

问题:

当我需要d 上的智能时,它会告诉我:

我不明白为什么T 不被推断为Movie

看看有多少位置推断TMovie

我怎样才能让这些电影字段出现,而不更改为Ienumerable&lt;Movies&gt;

【问题讨论】:

  • 泛型不是这样工作的。
  • 当您将其更改为 &lt;Movie&gt; 时,编译器就会知道您正在使用 Movie 项目。使用&lt;T&gt;,编译器将如何在方法中解析该类型参数?
  • 当 AddSort 被调用时会发生什么?
  • @BoltClock 是的,我忘了添加通用约束。 ( 太累了)。谢谢。 我投票关闭它。

标签: c# generics


【解决方案1】:

在编译Sorter 类时,编译器不知道它会是什么类型,因此它无法判断将使用它的用户是否具有Year 属性。

但是,您可以使用where constrains:

class Sorter<T> where T: Movie

这样编译器就知道T 的给定类将具有Year 属性以及其他属性

在泛型类型定义中,where 子句用于指定 对可用作类型参数的类型的约束 泛型声明中定义的参数。例如,您可以 声明一个泛型类 MyGenericClass,这样类型参数 T 实现了 IComparable 接口:

正如它所说,你甚至不必这样做

class Sorter<T> where T: Movie

我们可以满足

class Sorter<T> where T: ImyInterface

ImyInterface 将包含NameYear 的属性。

【讨论】:

  • 但这首先违背了拥有泛型的目的。为什么是Sorter&lt;T&gt; 而不仅仅是MovieSorter
  • @w0lf:您可以约束类型参数,同时仍保持其多态性。
  • @BoltClock 但是应该有两个类:Sorter&lt;T&gt;MovieSorter : Sorter&lt;T&gt;,不是吗?
  • @BoltClock 是的,我的意思是Sorter&lt;T&gt; where T: Movie 相当于MovieSorter,其中T 的所有出现都被Movie 替换(即非泛型类)跨度>
【解决方案2】:

我没有尝试此代码,但我认为您应该能够按照以下方式进行操作:

foreach(var func in funcs)
    movs = movs.OrderBy(func);

简单地将排序函数委托给 OrderBy 方法,而无需关心这些函数是什么以及 T 是什么类(这违背了泛型的目的)。

【讨论】:

    【解决方案3】:

    以下是我对您的问题和意图的解释:

    1>您正在使用 Sorter 类与非泛型 Sorter ,因为您打算让此类处理多种类型。

    2> 因为对于 AddSort 方法,您希望它基于 Movie 类成员,因此这表明您将拥有基于 Movie 类的派生类,例如 XYXMovie:Movie 等,Sorter 将用于这些类。

    如果我的上述观察是正确的,那么您需要将您的 Sorter 类绑定到基类“Movie”,以便它可以处理从类 Movie 派生的所有类型。

    为此,您必须使用 where 约束,例如 class Sorter where T: Movie。

    这使您的 Sorter 类与基类 Movie 绑定,但可以处理其所有子类。

    【讨论】:

      猜你喜欢
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 2019-02-17
      相关资源
      最近更新 更多