我正在使用工厂创建IComparer<User>对象以对用户列表进行排序。

我有2个类:AscendingDescending,都实现了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对象,所以出了什么问题?
奇怪的是,我可以使用(不必要的?)强制转换来修复错误:

// 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的编译时类型,反之亦然。它不会搜索两种类型的所有接口和基类,以尝试找到它们的一些“常见”类型。 (即使这样做,它将如何通过多个通用接口处理此案?)

这就是语言的设计方式。与您的方法的返回类型无关,在尝试解析?:表达式时不能将其考虑在内。

您已经找到解决方案,可以将X和/或Y显式转换为所需的类型。



回答了您的问题后,我也对不编写两个类AscendingDescending的方法提出了建议。您可以这样创建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))
  ;


因此(可能)您的这两类都不需要。

09-26 06:13