加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么C#编译器允许使用Linq执行强制转换但不允许使用括号?

发布时间:2020-12-15 19:51:11 所属栏目:百科 来源:网络整理
导读:我有一个通用类NamedValue TValue: public class NamedValueTValue{ public string Name { get; set; } public TValue Value { get; set; }} 我有第二个通用类,NamedValueSource TValue包含List NamedValue TValue: public class NamedValueSourceTValue{
我有一个通用类NamedValue< TValue>:

public class NamedValue<TValue>
{
    public string Name { get; set; }
    public TValue Value { get; set; }
}

我有第二个通用类,NamedValueSource< TValue>包含List< NamedValue< TValue>>:

public class NamedValueSource<TValue>
{
    public List<NamedValue<TValue>> NamedValues { get; set; }

    public NamedValueSource()
    {
        NamedValues = GetNamedValues().Cast<NamedValue<TValue>>().ToList();
    }

    private IEnumerable<NamedValue<bool>> GetNamedValues()
    {
        var yesNamedValue = new NamedValue<bool> { Name = "Yes",Value = true };
        var noNamedValue = new NamedValue<bool> { Name = "Yes",Value = false };
        yield return yesNamedValue;
        yield return noNamedValue;
    }
}

以下测试代码完美运行(断言传递):

public class Tester
{
    public Tester()
    {
        var source = new NamedValueSource<bool>();
        Debug.Assert(source.NamedValues[0].Name == "Yes");
    }
}

现在,这是有趣的部分.如果我尝试在GetNamedValues()中执行强制转换,代码将无法编译:

public class NamedValueSourceFail<TValue>
{
    public List<NamedValue<TValue>> NamedValues { get; set; }

    public NamedValueSourceFail()
    {
        NamedValues = GetNamedValues().ToList();
    }

    private IEnumerable<NamedValue<TValue>> GetNamedValues()
    {
        var yesNamedValue = new NamedValue<bool> { Name = "Yes",Value = false };
        yield return (NamedValue<TValue>)yesNamedValue; // ERROR: cannot convert type
        yield return (NamedValue<TValue>)noNamedValue; // ERROR: cannot convert type
    }
}

为什么NamedValueSource< TValue> NamedValueSourceFail< TValue>编译出错了?具体来说,为什么我能够使用Linq执行演员表而不是使用良好的ol’parantheses?

编辑

如果从接受的答案的评论主题中不完全清楚,我只需要先转换为对象,然后我将被允许转换为NamedValue< TValue>.这可能是Linq Cast方法在幕后工作的方式.

解决方法

在第二个示例中,您尝试转换NamedValue< bool>到NamedValue< TValue> – 这不起作用,因为转换必须对任何类型参数有效.你无法转换NamedValue< bool>到NamedValue< int>或NamedValue< string>或NamedValue< AnythingElSEOtherThanBool>.

一种解决方案是使NamedValueSource< TValue> abstract,以及它的GetNamedValues()方法,然后创建一个类BooleanNamedValueSource:NamedValueSource< bool>在测试中使用的类.

在linq的情况下,编译器没有完成转换;强制转换发生在已经编译的方法中.所有编译器都知道它正在调用一个采用IEnumerable< bool>的方法.并返回IEnumerable< TValue>.转换的细节对编译器完全不可见.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读