【问题标题】:Implementing IComparable<T>实现 IComparable<T>
【发布时间】:2012-10-05 14:16:36
【问题描述】:

我在尝试调整 Jon Skeet 的书中 C# 中的清单 3.4 时收到以下错误消息...

类型“list_3_4.Dog”不能用作泛型类型或方法“list_3_4.Program.CompareToDefault(T)”中的类型参数“T”。 没有从“list_3_4.Dog”到“System.IComparable”的隐式引用转换。

这是我的代码...

using System;

namespace list_3_4
{
     class Program
     {
          static void Main(string[] args)
          {
               //string mystring;
               Dog d = new Dog("howie");

               Console.WriteLine(CompareToDefault("x"));
               Console.WriteLine(CompareToDefault(10));
               Console.WriteLine(CompareToDefault(0));
               Console.WriteLine(CompareToDefault(-10));              
               Console.WriteLine(CompareToDefault(DateTime.MinValue));

               Console.WriteLine(CompareToDefault(d));

               Console.ReadKey();
          }

          static int CompareToDefault<T> (T value) where T: IComparable<T>
          {
               return value.CompareTo(default(T));               
          }

     }

     public class Dog 
     {
          private string _name;

          public Dog(string name)
          {
               _name = name;
          }
         }
}

如何添加像“Dog”这样的引用类型来处理 Jon Skeets 代码列表???我知道 Dog 需要实现 IComparable 但我不知道怎么做!

【问题讨论】:

  • 您的Dog 类似乎没有实现IComparable&lt;Dog&gt;,正如通用约束where T : IComparable&lt;T&gt; 所指定的那样。
  • +1 我可以复制、粘贴和使用的代码示例。虽然一个问题会很好大声笑
  • 以下不会工作 public class Dog : IComparable,我试过 public class Dog: IComarable...有效!
  • @DemetriusBerlioz 这对于引用类型来说是无意义的,因为它们将始终默认为 null 使用 default(T),因此您最好只测试 null:if (d == null)
  • @AdamHouldsworth 感谢您为我解决这个问题!

标签: c# generics


【解决方案1】:

你通过说你需要一个类型 T 来定义方法,它是一个 IComparable&lt;T&gt;

where T: IComparable<T>

但是Dog 没有实现IComparable&lt;Dog&gt;

你需要做的:

public class Dog : IComparable<Dog>
{
 //this will allow you to do a quick name comparison
 public string Name { get; set;}
 public int CompareTo(Dog other)
 {//compare dogs by name
        return this._name.CompareTo(other.Name);
 }
}

注意default(T) 将为引用类型返回 null,因此您应该在某处进行 null 检查。阅读default on msdn

【讨论】:

  • @Demetrius 您决定的最终实现应该对 _nameotherother.Name 进行空值检查。
  • 您实际上并不需要 Name 属性。如果你确实添加了它,你至少也应该将 setter 设为私有。
  • @AdamHouldsworth 或者你可以使用静态的string.Compare 为你做空检查。
  • 是的,我尝试了你指出的实现,但没有意识到“CompareTo”附加到什么......只是对象本身......就像在 this.CompareTo(other) ……那行不通。正如亚历克斯在上面指出的那样,它不在属性范围内..._name.CompareTo(other._name)...如果没有属性怎么办???
  • @Servy 够公平的。我不记得实现细节,所以我不完全确定other 是否也需要空检查。为了清楚起见,我总是倾向于这样做,但我从未真正测试过,哈哈
【解决方案2】:

您的Dog 类应该实现IComparable&lt;T&gt;

 public class Dog: IComparable<Dog>
 {
      private string _name;

      public Dog(string name)
      {
           _name = name;
      }

      public int CompareTo( Dog other )
      {
           if (other == null)
               return 1;
           return string.Compare( _name, other._name );
      }
 }

【讨论】:

  • public class Dog: IComparable 不工作,只有 public class Dog: IComparable 工作......有点......现在我得到一个 NullReferenceException ???跨度>
  • @DemetriusBerlioz 我已经为other == null 添加了检查,现在应该可以使用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多