Подтвердить что ты не робот

Явный/неявный оператор рассылки не работает при использовании оператора LINQ.Cast()

Я пытаюсь использовать класс, который имеет явный (но также не работает) с неявным оператором литья, который терпит неудачу при использовании функции LINQ Cast<T>(). Вот определения двух классов

public class DatabaseInfoElement : ConfigurationElement
{
    [ConfigurationProperty("AllowedServer", IsRequired = true)]
    public string AllowedServer { get { return (string)base["AllowedServer"]; } }

    [ConfigurationProperty("DatabaseName", IsRequired = true)]
    public string DatabaseName { get { return (string)base["DatabaseName"]; } }

    [ConfigurationProperty("SqlInstance", IsRequired = true)]
    public string SqlInstance { get { return (string)base["SqlInstance"]; } }

    public static explicit operator DatabaseInfo(DatabaseInfoElement element)
    {
        return new DatabaseInfo(element.AllowedServer, element.DatabaseName, element.SqlInstance);
    }

}

public class DatabaseInfo
{
    public DatabaseInfo(string allowedServer, string sqlInstance, string databaseName)
    {
        AllowedServer = allowedServer;
        SqlInstance = sqlInstance;
        DatabaseName = databaseName;
    }

    public string AllowedServer { get; set; }
    public string SqlInstance { get; set; }
    public string DatabaseName { get; set; }
}

Вот код, который я использую для его проверки.

//Gets the ConfigurationSection that contains the collection "Databases"
var section = DatabaseInfoConfig.GetSection();

//This line works perfectly.
DatabaseInfo test = (DatabaseInfo)section.Databases[0];

//This line throws a execption
var test2 = new List<DatabaseInfo>(section.Databases.Cast<DatabaseInfo>());

Вот исключение, которое я получаю

System.InvalidCastException was unhandled by user code
  HResult=-2147467262
  Message=Unable to cast object of type 'Server.Config.DatabaseInfoElement' to type 'Server.DatabaseInfo'.
  Source=System.Core
  StackTrace:
       at System.Linq.Enumerable.d__b1`1.MoveNext()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at Sandbox.Main() in E:\Code\Sandbox\Program.cs:line 82
  InnerException: 

Что я делаю неправильно в своем литье, чтобы заставить это работать так, как я хочу?

4b9b3361

Ответ 1

Когда вы определяете явные/неявные операторы приведения, они привязываются к сайтам-вызовам во время компиляции. Вот почему работает первая строка: компилятор может разработать всю необходимую информацию о типе, и поэтому он может заменить ваш собственный явный оператор литья для стандартного.

Однако, поскольку Cast<T> просто выполняет общий набор, компилятор не знает о вашем операторе, и поэтому он игнорируется. Результат: недопустимое исключение литья.

Вы можете обойти это, выполнив .Select(x => (DatabaseInfo)x). В качестве альтернативы вы можете добавить метод под названием ToDatabaseInfo(), чтобы вы не скрывали, что происходит на самом деле.