【问题标题】:Understanding interface casting [duplicate]了解接口转换[重复]
【发布时间】:2017-09-06 17:50:43
【问题描述】:

为什么我可以将 Component 类实例转换为如下接口:

public Component FindComponent<T>()
{
    var comp = (from c in components
                where typeof(T).IsAssignableFrom(c.GetType())
                select c).FirstOrDefault();

    return comp;
}

foreach(var a in actors)
{
    IHealth health = a.FindComponent<IHealth>() as IHealth;
}

但如果我这样做,我不能将它投射到 FindComponent() 中:

public T FindComponent<T>()
{
    var comp = (from c in components
                where typeof(T).IsAssignableFrom(c.GetType())
                select c).FirstOrDefault();

    return comp as T;
}

因为这给出了错误:类型参数“T”不能与“as”运算符一起使用,因为它没有类类型约束或“类”约束。

用户不必在FindComponent() 之后进行投射会更容易。 Unity 3D 具有类似的功能,您不必在它返回后进行投射,我不确定它如何在 FindComponent() 中进行投射,但我正在尝试复制它。

【问题讨论】:

  • 在函数中添加where T : classpublic T FindComponent&lt;T&gt;() where T : class
  • 没有改变任何东西。同样的错误。
  • 旁注:您可以通过以下方式简化您的第一个 linq 查询:var comp = components.FirstOrDefault(c =&gt; typeof(T).IsAssignableFrom(c.GetType())
  • @AleksAndreev 我个人更喜欢类似 sql 的语法。
  • 你的方法可以简单地看起来像:return components.OfType&lt;T&gt;().FirstOrDefault();

标签: c#


【解决方案1】:

如果转换失败,'as' 关键字会给你一个空值。但在这种情况下,您需要做的是隐式转换,因为您已经检查过这是可能的。

return (T) comp;

【讨论】:

  • 这给了我错误:无法将类型“组件”转换为“T”。演员表是多余的,但如果我删除演员表,我会收到错误:无法将类型“组件”隐式转换为“T”。
  • 好的。 “组件”是否可查询/列表/任何实现 OfType 方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 2020-01-15
  • 2018-01-15
  • 1970-01-01
  • 2010-12-13
  • 2010-11-05
相关资源
最近更新 更多