LINQ匿名铸造异常

时间:2014-07-18 16:12:20

标签: c# linq

LINQ的新手......以为我会给它一个“简单”的尝试让我的脚湿透(可以这么说)......我去了MS的网站(101简易linq或类似的东西)举了一个例子并试图修改它。

以下是我正在使用的课程:

public class RPt
{
    public RPt(int n, LatLon ll, int pt){Road = n;LL = ll;Pt = pt;}
    public int Road;
    public LatLon LL;
    public int Pt;
}

public class dRpt : RPt
{
    public dRpt(double d, RPt r) : base(r.Road, r.LL, r.Pt){D = d;}
    public double D;
};

public class LatLon
{
    public LatLon() { Latitude = 0.0; Longitude = 0.0; }
    public LatLon(double lat, double lon){ Latitude = lat; Longitude = lon; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class RoadList : List<RPt>
{
    public RoadList(){}

    public void FillIt()
    {
        RPt ll = null;
        ll = new RPt(1, new LatLon(37.252450, -122.058259), 10); this.Add(ll);
        ll = new RPt(1, new LatLon(37.248640, -122.068356), 20); this.Add(ll);
        ll = new RPt(1, new LatLon(37.254100, -122.089025), 30); this.Add(ll);
        ll = new RPt(1, new LatLon(37.261881, -122.102711), 40); this.Add(ll);
        ll = new RPt(1, new LatLon(37.260418, -122.112793), 50); this.Add(ll);
        ll = new RPt(1, new LatLon(37.256413, -122.116153), 60); this.Add(ll);
        ll = new RPt(1, new LatLon(37.258525, -122.121971), 70); this.Add(ll);
        ll = new RPt(2, new LatLon(37.258525, -122.121971), 10); this.Add(ll);
        ll = new RPt(2, new LatLon(37.259727, -122.124134), 20); this.Add(ll);
        ll = new RPt(2, new LatLon(37.259971, -122.129823), 30); this.Add(ll);
        ll = new RPt(2, new LatLon(37.267248, -122.138307), 40); this.Add(ll);
        ll = new RPt(2, new LatLon(37.285609, -122.152232), 50); this.Add(ll);
        ll = new RPt(2, new LatLon(37.291702, -122.156238), 60); this.Add(ll);
        ll = new RPt(2, new LatLon(37.293491, -122.161288), 70); this.Add(ll);
    }
}

我试图使用LINQ语句(如sql join)过滤RoadList,然后将过滤后的结果集转换回我的RoadList而不是匿名'var'。

以下是设置功能:

    RoadList hwy;
    private void TestLinq()
    {
        hwy = new RoadList();
        hwy.FillIt();

        List<int> list = new List<int>() { 10 };

        try
        {
            RoadList filtered = LinqFilter(list, hwy);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }

    }

这是LINQ代码:(和问题区域)

    private RoadList LinqFilter(List<int> list, RoadList input)
    {
        RoadList retval = null;

        // this does what I want it to do...
        // returns only the list of RPt objects that match the ints
        // in the incoming list
        var q2 =
        from c in input
        join p in list on c.Pt equals p
        select new { RPt = c };

        retval = (RoadList)q2;  // <<== This is where I get the exception !

        foreach (RPt rpt in retval)
        {
            Debug.WriteLine(rpt.ToString());
        }

        return retval;
    }

以下是我得到的例外情况:

Unable to cast object of type '<JoinIterator>d__61`4[deleteMe_Test.RPt,System.Int32,System.Int32,<>f__AnonymousType1`1[deleteMe_Test.RPt]]' to type 'deleteMe_Test.RoadList'."

帮助...需要返回我的类对象,以便将其返回到另一个函数!

谢谢。

1 个答案:

答案 0 :(得分:5)

您尝试使用q2,就像它是RoadList一样,但事实并非如此。它是IEnumerable<'a>,其中'a是具有public RPt RPt属性的anonymous type。完全不同的事情......

匿名类型是不必要的,因此首先更改为:

var q2 =
from c in input
join p in list on c.Pt equals p
select c;

获得IEnumerable<RPt>。现在您需要创建一个包含此内容的RoadList。我建议您在RoadList中创建一个新的构造函数,该构造函数需要IEnumerable<RPt>并将其传递给List<T>(IEnumerable<T>)构造函数

public RoadList(IEnumerable<RPt> items) : base(items) {}

然后你可以:

retval = new RoadList(q2);

其他一切都应该按预期工作。