你能在运行时更改类型的Name属性值吗?

3

能否更改/覆盖类型的Name属性?

给定类定义:

class Sample
{}

您能更改typeof(Sample).Name返回的值吗?

我正在使用定制序列化库,它在源代码中直接使用typeof(T).Name

writer.WriteStartElement(typeof(T).Name);
writer.WriteValue(item);
writer.WriteEndElement();

说到“名字”,您是指变量的名称吗? - sertsedat
1
@CodeCaster,“因为有些我无法控制的代码正在使用这个值进行序列化。”是上下文。 - Marc Gravell
1
我查看了.Name的实现,发现它基本上在一个非托管函数中终止:[SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("QCall", CharSet=CharSet.Unicode)] private static extern void ConstructName(RuntimeTypeHandle handle, TypeNameFormatFlags formatFlags, StringHandleOnStack retString)。因此,如果有欺骗这个函数的方法,那么它是完全保密和未记录的。 - Marc Gravell
2
你不能使用一个XML操作类来修改生成的XML吗? - CodeCaster
好主意;重命名一个元素对于XSLT来说应该是相当简单的。 - Marc Gravell
4个回答

3
不,你不能在运行时更改Type.Name。但是,大多数序列化库允许你通过提供自定义“绑定器”(等等)或通过使用属性注释类型来指示首选名称来控制名称处理(请注意:允许属性的大多数库也允许通过序列化库的运行时配置提供名称)。
那么,重要的问题是:这里使用的是哪个序列化库?
如果序列化库不支持此功能,并且无法更改,则除了重命名Sample之外,唯一的选择是创建一个类型(手动创建或通过TypeBuilder在运行时创建),该类型看起来像原始类型,但具有不同的代码,并且类似地:创建将两种类型之间进行转换的代码。

如果已经有一个名为TheNameIWant的类,那么我就无法重命名Sample或在运行时创建类型了... - lastr2d2
2
最后,您可以在不同的命名空间中实现。 - CodeCaster

1
我不知道任何实现此任务的方法。CLR可以使用通过引用对象进行类似的操作,但我怀疑它是否允许您以这种方式“重命名”您的类或其属性(字段)。
最好的选择是要么遵循旧代码,要么(更好的选择)替换或更改序列化例程以使其更灵活。

0
关于使用BCL中的XmlSerialization库进行XML序列化,您可以使用以下属性覆盖要生成的xml元素名称:
[XmlElement("SomeOtherName")]
public class Sample{...}

这完全取决于使用的序列化库;使用的方法差别很大。 - Marc Gravell
@MarcGravell 是的,我特别指的是 XmlSerialization 库。 - Yair Nevet
谢谢,但这对我来说不是一个选项,因为我正在使用一个自定义序列化库,它在源代码中使用了'typeof(T).Name'... - lastr2d2
@lastr2d2,那么你的选择有:1)接受它,2)在你的代码中更改“class Sample”的名称,3)添加一个单独的DTO类型,仅用于序列化,4)编写大量代码以自动生成具有不同名称的DTO。我猜我会选择“2”或“3”。 - Marc Gravell

0

根据您的问题,您提到您想在序列化过程中控制名称。

如果您想在序列化过程中更改名称,您可以使用以下属性

[DataContract(Name = "NewName")] 
[XmlRoot("NewName")] 
class Sample
{
}

这完全取决于使用的序列化库;使用的方法差别很大。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接