不必要的强制转换为iccomparer

本文关键字:iccomparer 转换 不必要 | 更新日期: 2023-09-27 18:13:21

我知道如何将IComparer接口与提供自定义排序方法的helper类一起使用。例如,这里有一个典型的例子,它非常像我在网上看到的所有例子,包括微软的在线帮助页面:

// This helper class is used to sort an array of people by name, 
// where 'Person' is a class type.
public class PeopleNameComparer : IComparer
{
  // Test the name of each object.
  int IComparer.Compare(object o1, object o2)
  {
     Person p1 = o1 as Person;
     Person p2 = o2 as Person;
     if (p1 != null && p2 != null)
        return string.Compare(p1.Name, p2.Name);
     else
        throw new ArgumentException("Parameter is not a Person!");
  }
}

我也明白,如果我们有一个类型为Person (myPeople)的数组,那么我们可以对这个数组进行排序:

Array.Sort(myPeople, new PeopleNameComparer());

在本例中,我们创建了一个新的PeopleNameComparer对象,其类型为IComparer,并将其作为第二个参数传递给Array.Sort()方法。

现在,为了使事情更简洁,我们可以实现一个属性,为对象用户提供一种更友好的方式来调用自定义排序:

public static IComparer SortByName
{ get { return (IComparer)new PeopleNameComparer(); } }

我不理解这种属性的是为什么所有的例子都使用(IComparer) cast来转换新创建的助手类(PeopleNameComparer在这个例子中)到一个IComparer对象,当这个对象已经是IComparer类型?我试过没有强制转换,代码似乎工作得很好:

// This property seems to work fine without the cast?
public static IComparer SortByName
{ get { return new PeopleNameComparer(); } }
如果"new"关键字返回一个普通的系统,我可以理解它。对象类型,然后必须将其强制转换为适当的iccomparer,但在这里看不到强制转换的必要性。但是我遵循了微软的例子,我的例子与我的Pro c#书中的例子相似。

这里有必要强制转换的原因吗?

不必要的强制转换为iccomparer

使用显式强制转换使更显式。请原谅这句老生常谈……但就是这样。它有助于使代码更具可读性。

在某些情况下,如果有多个可能的选项,显式强制转换可以帮助运行时消除强制转换的歧义,但这似乎不会发生在返回类型上。只在表达式中。下面是一个在表达式中需要显式强制转换的常见示例:

public class StringEnumerable : IEnumerable, IEnumerable<String>
{
    IEnumerator<String> IEnumerable<String>.GetEnumerator()
    {
        yield return "TEST";
    }
    public IEnumerator GetEnumerator()
    {
        // without the explicit cast of `this` to the generic interface the 
        // method would call itself infinitely until a StackOverflowException occurs
        return ((IEnumerable<String>)this).GetEnumerator();
    }
}

如果从非泛型接口实现中删除显式强制转换,将导致无限循环。

cast是多余的。

也许在从其他地方重构代码之前,这是必要的。

通常情况下,你会看到在漫长的系统生命周期中,当设计发生变化时,代码中会留下很多无用的东西。

随着时间的推移,当语言特性发生变化(例如c#自动属性)时,您可能还会看到其他冗余结构。

我认为冗余代码会降低可读性,像Resharper这样的工具会警告你并帮助你删除它们。

如果您的问题仅仅是为什么示例将PeopleNameComparer转换为IComparer,那么您是正确的,这根本没有必要。我想这是为了清晰地向初学者演示结果和界面之间的隐含关系。

我不知道"所有"的例子,但确实代码的两个变体应该工作相同。也许他们只是认为显式强制转换更容易读懂。