Extension方法返回InvalidCastException

时间:2016-02-28 13:04:24

标签: c# exception exception-handling extension-methods

我正在尝试学习如何使用扩展方法并创建了自己的扩展方法。现在我尝试运行我的代码,但Visual Studio给了我一个错误,我有一个未处理的InvalidCastException,所以我处理它并尝试运行它。

我必须在catch块中返回null,所以我有另一个未处理的异常,也打印出来。

现在,当我尝试运行此代码时,输​​出为

InvalidCastException NullReferenceException

Generic conversion method throw InvalidCastException尝试通过向演员表添加(动态)来获得此处找到的解决方案,结果相同。

注意,我有一个java背景,而不是C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication4
{

class Program
{
    static void Main(string[] args)
    {
        Reeks r = new Reeks();
        IEnumerable<int> selectie = r.TakeRange(10, 1000);
        try
        {
            foreach (int i in selectie)
            {
                Console.WriteLine("selectie: {0}", i);
            }
        }
        catch (NullReferenceException)
        {
            Console.WriteLine("NullReferenceException");
        }
        Console.ReadLine();

    }
}

static class MyExtension
{
    public static Reeks TakeRange(this Reeks r, int start, int end)
    {
        try
        {
            return (Reeks)r.Where(i => i > start && i < end);
        }
        catch (InvalidCastException) { 
            Console.WriteLine("InvalidCast"); return null; 
        }
    }
}


public class Reeks : IEnumerable<int>
{

    public Reeks()
    {

    }

    public IEnumerator<int> GetEnumerator()
    {
        int start = 2;
        yield return start;
        for (; ; )
        {
            int nieuw = start * 2;
            yield return nieuw;
            start = nieuw;

        }

    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }


}


}

3 个答案:

答案 0 :(得分:1)

您正在Where块中投射try来电的返回值,以键入Reeks

return (Reeks)r.Where(i => i > start && i < end);

但是,没有任何名为Where的方法实际上返回类型为Reeks的对象。该代码调用Enumerable.Where,它返回某种IEnumerable实现,但绝对不是您自己的类型。

您必须实现一个名为Where的新(扩展或实例)方法,该方法可以在Reeks对象上调用,并返回Reeks个对象。或者您可以简单地接受Where未返回Reeks而只是期望IEnumerable<int>的事实。

答案 1 :(得分:1)

您应该更改静态方法,使其返回IEnumerable <int>,看看这个:

static class MyReeksExtension {
        public static IEnumerable <int> TakeRange(this IEnumerable<int> r, int start, int end) {
            return r.Where(i => i > start && i < end);
        }
    }

确保您的选择&#39;也属于这种类型:

IEnumerable<int> selectie = r.TakeRange(10, 1000);

        foreach (int n in selectie)
            Console.Write("{0}; ", n);

没问题,我也得找到帮助:P

答案 2 :(得分:-1)

您应该更改以下行 return (Reeks)r.Where(i => i > start && i < end);return (Reeks)(r.Where(i => i > start && i < end).ToList().AsEnumerable());

where子句返回一个应转换为列表的枚举器。此外,您可以尝试使用linq中的skiptake替换上面的代码段。