36

我正在尝试使用具有显式(但也因隐式失败)强制转换运算符的类,该运算符在使用 LINQCast<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 未被用户代码处理
  H结果=-2147467262
  消息=无法将“Server.Config.DatabaseInfoElement”类型的对象转换为“Server.DatabaseInfo”类型。
  源=System.Core
  堆栈跟踪:
       在 System.Linq.Enumerable.d__b1`1.MoveNext()
       在 System.Collections.Generic.List`1..ctor(IEnumerable`1 集合)
       在 E:\Code\Sandbox\Program.cs:line 82 中的 Sandbox.Main()
  内部异常:

我在选角时做错了什么以使其按我想要的方式工作?

4

1 回答 1

55

当您定义显式/隐式转换运算符时,它们在编译时绑定在调用站点。这就是第一行有效的原因:编译器可以计算出所有需要的类型信息,因此它可以用您自定义的显式转换运算符替换默认的。

然而,由于Cast<T>只是执行一个泛型转换,编译器不知道你的操作符,因此它被忽略了。结果:无效的强制转换异常。

您可以通过执行.Select(x => (DatabaseInfo)x). 或者,您可以添加一个名为 的方法ToDatabaseInfo(),这样您就不会隐藏实际发生的事情。

于 2012-11-09T22:07:41.737 回答