我有一个奇怪的场景,我似乎无法绕过头脑。我有以下基类:
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?!
我做错了什么?
答案 0 :(得分:4)
你混合了两件事:一个对象的运行时类型和一个字段的编译类型。
Data
字段的类型仍为Note
。您可以通过反射验证自己。例如,以下内容将打印“注意”:
Console.Write(
typeof(DataRequest<Note>).GetProperty("Data").PropertyType.Name);
此字段包含的对象的Type
可以是Note
或任何派生类型。将对象分配给基类的变量不会更改其运行时类。由于GetType()
返回对象的类型,因此您获得实际的派生类型(NoteAttachment
)。
答案 1 :(得分:3)
当@Alexi回答你的第一个问题时,请在评论中尝试第二个问题。将NotownType属性添加到您的笔记类中,如下所示:
[KnownType(typeof(NoteAttachment)]
public class Note