简体   繁体   English

C#通用协变错误

[英]C# Generic Covariant Error

following is my code, i don't know why DateTime can not change to Object , any idea to resolve this problem? 以下是我的代码,我不知道为什么DateTime不能更改为Object,任何解决此问题的想法?

    public class Test
    {
        public DateTime CreatedTime { get; set; }
    }
    public class Test1
    {

    }
    public class Test2 : Test1
    {
    }
    static void Main(string[] args)
    {

        Func<Test, ArgumentException> fn1 = null;
        Func<Test, Exception> fn2 = fn1;// success 

        Func<Test, Test2> fn3 = null;
        Func<Test, Test1> fn4 = fn3;//success  

        Func<Test, DateTime> expression1 = p => p.CreatedTime;
        Func<Test, object> s = expression1; // Cannot implicitly convert type 'System.Func<IlReader.Program.Test,System.DateTime>' to 'System.Func<IlReader.Program.Test,object>'    
        Func<Test, ValueType> s2 = expression1; // cannot implicatily convert .... 
    }

DateTime is a value type. DateTime是一个值类型。 Converting a value type to a reference type ( object in this case) is a representation-changing conversion. 将值类型转换为引用类型(在这种情况下为object )是一种表示形式转换。 It requires boxing the value type. 它需要装箱值类型。 For reference types, this is not the case. 对于引用类型,不是这种情况。 CLR implements reference with pointers and all pointers have the same size. CLR使用指针实现引用,并且所有指针的大小均相同。 A reference to a derived class is merely interpreted as a reference to the base class. 对派生类的引用仅解释为对基类的引用。 For this reason, you cannot use covariance like that on value types. 因此,您不能在值类型上使用协方差。

Theoretically, it would have been possible for the compiler to generate an intermediate function like: 从理论上讲,编译器可能会生成一个中间函数,例如:

object compilerGeneratedFunction(Test t) {
    return (object)anonymousFunctionThatReturnsDateTime(t);
    // The above cast can be implicit in C# but I made it explicit to demonstrate
    // boxing that has to be performed.
}

Func<Test, DateTime> convertedFunction = compilerGeneratedFunction;

But the resulting delegate would point to an entirely different function causing bad things like not obeying delegate equality rules in C# spec. 但是,生成的委托将指向一个完全不同的函数,从而导致不好的事情,例如不遵守C#规范中的委托相等规则。 The design team has decided against generating such a function. 设计团队已决定不生成此类功能。

You're attempting to convert a delegate type Func<Test, DateTime> expression1 to a delegate type Func<Test, object> , not the DateTime field to object . 您正在尝试将委托类型Func<Test, DateTime> expression1转换为委托类型Func<Test, object> ,而不是将DateTime字段转换为object

If this was your original intention, use the lambda expression syntax instead, like so: 如果这是您的初衷,请改用lambda表达式语法,如下所示:

Func<Test, object> s = p => p.CreatedTime;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM