c# - 将派生类转换为基类可以在使用泛型时保留派生知识

标签 c# .net generics inheritance

我有一个奇怪的场景,我似乎无法理解。我有以下基类:

public class Note
{
    public Guid Id { get; set; }
    public string SenderId { get; set; }
    ...
}

然后由以下类派生:

public class NoteAttachment : Note
{
    public string FileType { get; set; }
    public string MD5 { get; set; }
    ...
}

我使用这些类通过通用包装器与服务器通信:

public class DataRequest<T> : DataRequest
{
    public T Data { get; set; }
}

public class DataRequest
{
    public string SomeField { get; set; }
    public string AnotherField { get; set; }
}

所以我有一个 NoteAttachment发送到方法,但我需要包装一个 Note对象发送到服务器。所以我有以下扩展方法:

    public static DataRequest<T> GetDataRequest<T>(this T data)
    {
        DataRequest<T> dataRequest = new DataRequest<T>
        {
            SomeField = "Some Value",
            AnotherField = "AnotherValue",
            Data = data
        };

        return dataRequest;
    }

现在是问题。以下列方式调用扩展方法工作正常,但即使 DataRequest 类型是 DataRequest<Note> ,数据字段的类型为 NoteAttachment .

var noteAttachment = new NoteAttachment();

...

Note note = (Note)noteAttachment;

var dataRequest = note.GetDataRequest();

Debug.WriteLine(dataRequest.GetType()); //MyProject.DataRequest`1[MyProject.Note]
Debug.WriteLine(dataRequest.Data.GetType()); //MyProject.NoteAttachment <--WHY?!

我做错了什么?

最佳答案

您混合了两种东西:对象的运行时类型和字段的编译类型。

Data 字段的类型仍然是Note。你可以通过反射(reflection)自己验证。例如,以下将打印“Note”:

Console.Write(
     typeof(DataRequest<Note>).GetProperty("Data").PropertyType.Name);

该字段包含的对象的Type 可以是Note 或任何派生类型。将对象分配给基类的变量不会更改其运行时类。由于 GetType() 返回对象的类型,您可以获得实际的派生类型 (NoteAttachment)。

关于c# - 将派生类转换为基类可以在使用泛型时保留派生知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23020107/

相关文章:

c# - 是什么让这个计时器在范围内?匿名方法?

c# - NLog 给出异常可能的解释是缺少零参数和单个参数 Common.Logging.Configuration.NameValueCollection 构造函数

c# - LINQ + 加入嵌套的 foreach Razor 输出,从 groupby 写出标题行

c# - 更新 EF 4.1 中的记录

java - 使用 JAXB 映射通用的嵌套 XML 数据结构

c# - 如何调用类实例中的公共(public)函数?

c# - Delegate.CreateDelegate 不会将返回值装箱 - 是故意的,还是疏忽?

.net - 南希FX : Deserialize JSON

c# - 访问 lambda 表达式内泛型类型的属性

java - 我的泛型类型转换有什么问题?