1

以下是我的代码,我不知道为什么 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 .... 
    }
4

2 回答 2

6

DateTime是一个值类型。将值类型转换为引用类型(object在这种情况下)是一种表示改变的转换。它需要对值类型进行装箱。对于引用类型,情况并非如此。CLR 使用指针实现引用,并且所有指针具有相同的大小。对派生类的引用仅被解​​释为对基类的引用。出于这个原因,你不能像在值类型上那样使用协方差。

从理论上讲,编译器可以生成一个中间函数,例如:

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;

但是生成的委托将指向一个完全不同的函数,从而导致不遵守 C# 规范中的委托相等规则等不好的事情。设计团队决定不生成这样的功能。

于 2010-10-12T03:41:25.767 回答
0

您正在尝试将委托类型转换为Func<Test, DateTime> expression1委托类型Func<Test, object>,而不是将DateTime字段转换为object.

如果这是您的初衷,请改用 lambda 表达式语法,如下所示:

Func<Test, object> s = p => p.CreatedTime;
于 2010-10-12T03:36:40.890 回答