我正在使用工厂创建 IComparer<User>
对象对用户列表进行排序。
我有 2 节课:Ascending
和 Descending
, 都实现 IComparer<User>
.这是代码:
namespace Test
{
public class Program
{
public static void Main(string[] args)
{
List<User> users = new List<User>();
users.Add(new User("foo", "bar"));
// ...
IComparer<User> cmp = ComparerFactory.GetComparer("FirstName", true);
if (cmp != null)
{
users.Sort(cmp);
}
}
}
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public User(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
public class UserFirstNameComparer
{
public class Ascending : IComparer<User>
{
public int Compare(User u1, User u2)
{
return String.Compare(u1.FirstName, u2.FirstName, true);
}
}
public class Descending : IComparer<User>
{
public int Compare(User u1, User u2)
{
return new UserFirstNameComparer.Ascending().Compare(u1, u2) * -1;
}
}
}
public static class ComparerFactory
{
public static IComparer<User> GetComparer(string fieldName, bool ascending)
{
switch (fieldName)
{
case "FirstName":
return ascending ?
new UserFirstNameComparer.Ascending() : // ERROR IS HERE
new UserFirstNameComparer.Descending();
//...
}
return null;
}
}
但我收到一个错误(行:
new UserFirstNameComparer.Ascending() :
):Type of conditional expression cannot be determined because there is no implicit conversion between 'Test.UserFirstNameComparer.Ascending' and 'Test.UserFirstNameComparer.Descending'
我不明白这是什么意思,两者都是 IComparer 对象,那有什么问题?
奇怪的是,我可以使用(不必要的?) Actor 来修复错误:
// This works
return ascending ?
(IComparer<User>) new UserFirstNameComparer.Ascending() :
new UserFirstNameComparer.Descending();
// This works too
return ascending ?
new UserFirstNameComparer.Ascending() :
(IComparer<User>) new UserFirstNameComparer.Descending();
当然,当我在这两种情况下都进行转换时,它会起作用。但我不明白为什么它只适用于一个类型转换,以及为什么没有类型转换时它不起作用。有任何想法吗 ?
(我正在使用 VS 2012,.NET v4.0.30319)
最佳答案
表达方式
cond ? X : Y
只是 需要 (简化)
X
的编译时类型可隐式转换为 Y
的编译时类型, 或相反亦然。它不会搜索这两种类型的所有接口(interface)和基类来尝试找到它们的一些“常见”类型。 (即使是这样,它如何处理具有多个通用接口(interface)的情况?)这就是语言的设计方式。您的方法的返回类型是什么无关紧要,在尝试解析
?:
时无法考虑。表达。您已经找到了解决方案,可以转换
X
和/或 Y
显式地转换为所需的类型。回答了您的问题后,我还有一个建议,您可以如何在不编写两个类的情况下做到这一点
Ascending
和 Descending
.您可以创建 IComparer<>
像这样:return ascending
? Comparer<User>.Create((u1, u2) => String.Compare(u1.FirstName, u2.FirstName, true))
: Comparer<User>.Create((u1, u2) => String.Compare(u2.FirstName, u1.FirstName, true))
;
所以不需要(可能)你的这两类。
关于c# - 不必要的接口(interface)转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24652983/