【问题标题】:C# can not using **as** to cast base class to derived classC# 不能使用 **as** 将基类转换为派生类
【发布时间】:2013-05-14 17:49:51
【问题描述】:
class Building {
}

class Home: Building {
}

private List<Building>   buildings;
public T[] FindBuildings<T>() {       
    return buildings.FindAll(x => x is T).ToArray() as T[];
}

我有一个列表来保存地图上的所有建筑物,并编写一个函数来查找特定的建筑物类型。 我想使用FindBuildings&lt;Home&gt;() 来获取一个包含地图上所有住宅建筑的数组,但是当我运行代码时,我发现函数总是返回null,似乎as 不起作用。这是否意味着as 不能使用泛型类型参数?

所以,我改一下代码:

private List<Building>   buildings;
public Building[] FindBuildings<T>() {       
    return buildings.FindAll(x => x is T).ToArray();
}

使用FindBuildings&lt;Home&gt;() as Home[] 访问地图上的住宅建筑。但是......它仍然为空。

我看到了一个Unity3d的例子,给我看使用'as'转换数组类型,为什么我失败了?

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void OnMouseDown() {
        HingeJoint[] hinges = FindObjectsOfType(typeof(HingeJoint)) as HingeJoint[];
        foreach (HingeJoint hinge in hinges) {
            hinge.useSpring = false;
        }
    }
}

【问题讨论】:

标签: c# generics casting


【解决方案1】:

你需要这样做:

return buildings.OfType<T>.ToArray();

解释为什么你的尝试没有成功。

表达式buildings.FindAll(x =&gt; x is T) 的类型是List&lt;Building&gt;。这是因为buildings 本身就是一个List&lt;Building&gt;,而FindAll 并没有神奇地改变返回值中项目的类型。因此,ToArray() 产生一个Building[]

as 运算符仅在直接强制转换有效的情况下返回非空值。由于从Building[]Home[] 的转换无效,所以as 总是产生null。不要对将 Home[] 转换为 Building[] 是有效的事实感到困惑。

【讨论】:

    【解决方案2】:

    问题在于Building[] 不是Home[]。所以这段代码:

    public T[] FindBuildings<T>() {       
        return buildings.FindAll(x => x is T).ToArray() as T[];
    }
    

    ...总是尝试将Building[] 视为T[],并且当T 既不是Building 也不是Object 时将返回T[]。您需要先创建一个T[]。幸运的是,LINQ 实际上让你很容易做到这一点:

    public T[] FindBuildings<T>() {       
        return buildings.OfType<T>().ToArray();
    }
    

    重要的是OfType&lt;T&gt; 返回一个IEnumerable&lt;T&gt; - 而您对List&lt;Building&gt;.FindAll 的调用仍然返回一个List&lt;Building&gt;,所以ToArray 正在创建一个Building[]

    顺便说一句,我强烈建议使用强制转换而不是 as,除非它 有效as 返回 null。如果您希望强制转换失败成为错误条件,则直接强制转换指示通过异常立即,而不是稍后收到NullReferenceException,从而掩盖原始问题。

    【讨论】:

      猜你喜欢
      • 2017-01-08
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 2013-09-23
      相关资源
      最近更新 更多