使用LINQ时无效的Cast Exception

时间:2010-02-18 19:08:53

标签: c# linq exception

我是一个经典的新手...

我可以编译我的程序,但在运行程序时获得无效的广播加密

我的代码出了什么问题。我不知道该怎么做:(

这是我的代码(.net 3.5)

class Element{
    private int i;
    public int I { get { return i; } set { i = value; } }
    private string s;
    public string S { get { return s; } set { s = value; } }

    public Element(string _s, int _i) {
        this.s = _s;
        this.i = _i;
    }
}
class myDict : Dictionary<string, Element> {
    public void afunction() { 

    }
}

class Program {
    static void Main(string[] args) {

        myDict myDict = new myDict();
        myDict.Add("a", new Element("x", 23));
        myDict.Add("b", new Element("y", 48));

       var sortedDict = ((from entry in myDict orderby entry.Key descending select entry).Take(10));

       myDict = (myDict)sortedDict.ToDictionary(v => v.Key, v => v.Value);
        foreach (KeyValuePair<string, Element> kvp in myDict) {
            System.Console.WriteLine("-> " +kvp.Key + " " + kvp.Value);
        }
        Console.ReadLine();
    }
}

谢谢!迈克尔:)

6 个答案:

答案 0 :(得分:6)

  

您好

你好。

  

我是一个经典的新手。

欢迎登机。

  

我可以编译我的程序,但在运行程序时得到无效的强制转换异常

强制转换操作符通常意味着“我告诉编译器这个转换是有效的。如果我犯了错误,在运行时抛出一个无效的强制转换异常。”

  

我的代码出了什么问题。我不知道该去找什么。

那么,而不是给你一条鱼 - 字典上的演员是无效的 - 让我们教你如何捕捉自己的鱼。

在调试模式下编译程序并在调试器中运行它。调试器应该在异常的确切位置处中断。然后,您可以分析该确切站点的错误。

如果由于某种原因无法在调试器中运行代码,请在调试模式下编译程序并正常运行。当您收到异常时,请查看异常的“堆栈跟踪”部分。它应该具有异常站点的行号,以便您可以检查该代码。

如果由于某种原因你无法做到这一点,请使用异常消息尝试解决它。 “无效的强制转换异常”意味着不良行为是强制转换操作符的结果。程序中有两个位置使用了强制转换运算符。在字典中有一个显式的使用,在foreach循环中有一个隐含的用法。

许多人对后者的了解感到惊讶。当你说

foreach(Giraffe giraffe in animals)

实际上意味着“将动物名单中的每只动物都投放到长颈鹿身上,并且如果其中一只是老虎或小袋鼠或其他东西,则会给出无效的施法例外”。它并不意味着“忽略所有不是长颈鹿的动物” - 如果你想要那么,那就说

foreach(Giraffe giraffe in animals.OfType<Giraffe>())

问题几乎肯定会出现在这两个地方之一。

答案 1 :(得分:2)

我认为问题在于您将sortedDict.ToDictionary()的结果转换为myDict。

myDict = (myDict)sortedDict.ToDictionary(v => v.Key, v => v.Value);

答案 2 :(得分:2)

你不能这样做:

myDict = (myDict)sortedDict.ToDictionary(v => v.Key, v => v.Value);

当您致电ToDictionary时,您创建的是Dictionary<string, Element>,而不是myDict个实例。该演员表是无效的。

但是,没有理由(在这种情况下)这样做。您可以直接使用sortedDict结果。

如果您想这样做,我建议您添加myDict的{​​{1}}构造函数。然后你可以这样做:

IEnumerable<KeyValuePair<string,Element>>

然后,您可以执行以下操作:

,而不是演员表
class myDict : Dictionary<string, Element> {
     public myDict() {}
     public myDict(IEnumerable<KeyValuePair<string, Element>> pairs)
     {
          foreach(var pair in pairs)
               this.Add(pair.Key, pair.Value); // Add in all elements
     }
}

话虽如此,直接继承myDict myDict = new myDict(); myDict.Add("a", new Element("x", 23)); myDict.Add("b", new Element("y", 48)); var sortedDict = ((from entry in myDict orderby entry.Key descending select entry).Take(10)); myDict = new myDict(sortedDict); 是个坏主意。如果要创建自定义词典,则应将框架词典封装在自己的类中,并实现IDictionary<TKey,TValue>

答案 3 :(得分:2)

ToDictionary调用返回Dictionary<string, Element>。仅仅因为myDict是Dictionary<string, Element>并不意味着Dictionary<string, Element>是myDict。

答案 4 :(得分:0)

ToDictionary()不返回myDict类,它会返回Dictionary类。您无法从Dictionary投射到myDict,但由于myDict来自Dictionary,您可以采用其他方式投射。

答案 5 :(得分:0)

你的问题是你不能强制转换回myDict,因为它是一个比Dictionary更具体的类