我理解如何将IComparer接口与帮助程序类一起使用,这些辅助程序类提供自定义排序方法。例如,这是一个典型的例子,它非常像我在网上看到的所有例子,包括微软的在线帮助页面:
// 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)强制转换将新创建的辅助类(本例中为PeopleNameComparer)强制转换为IComparer对象IComparer的?我试过没有演员,代码似乎工作正常:
// This property seems to work fine without the cast?
public static IComparer SortByName
{ get { return new PeopleNameComparer(); } }
我可以理解,如果'new'关键字返回一个简单的vanilla System.Object类型,然后必须将其转换为适当的IComparer,但是在这里看不到需要进行转换。 但我遵循微软的例子,我的例子类似于我的Pro C#书中的一个例子。
为什么有必要在这里演员?
答案 0 :(得分:2)
演员表是多余的。
也许在代码被其他东西重构之前可能是必要的。
通常,在设计发生变化的长系统生命周期中,您会发现代码中存在大量漏洞。
当语言功能发生变化(即C#自动属性)时,您可能还会看到其他冗余结构。
我认为冗余代码会降低可读性,而像Resharper这样的工具会警告您并帮助您删除它们。
答案 1 :(得分:2)
使用显式强制转换更明确。原谅这个真理......但就是这样。它有助于使代码更具可读性。
在某些情况下,如果有多个可能的选项,那么显式强制转换可以帮助运行时消除转换的歧义,但这似乎不会出现在返回类型中。只在表达式中。以下是一个常见示例,您需要在表达式中进行显式强制转换:
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();
}
}
如果从非泛型接口实现中删除显式转换,则会导致无限循环。
答案 2 :(得分:1)
如果您的问题只是示例将PeopleNameComparer转换为IComparer的原因,那么您完全没有必要。我想这是为了清楚地向初学者证明结果和界面之间存在隐含的关系。
答案 3 :(得分:1)
我不知道“所有”示例,但实际上代码的两个变体应该完全相同。也许他们只是认为明确的演员更具可读性。