是否可以在部分 class 中向 属性 添加属性?

Is it possible to add an attribute to a property in a partial class?

我不认为这是可能的,但由于我没有从 MSDN 得到明确的说明,我觉得最好问问。假设我们有一个class如下。

public partial class Hazaa
{
  public int Shazoo { get; set; }
}

那么,我希望 Shazoo 被归类为 SuperCool 但是 我希望在另一个文件中这样做。由于我使用的是部分 classes,因此我可以 添加 新属性,如下所示。

public partial class Hazaa
{
  [SuperCool]
  public int Wheee { get; set; }
}

但是我可以通过在后者中编写代码来对第一个示例中声明的 属性 进行属性化吗?我怀疑这是可能的,但我很乐意接受纠正。如果是这样,语法是什么?

不,你不能。

您只能将属性附加到您在那里声明的成员,除非该成员也声明为部分成员(以便您可以在其他地方重新实现它),否则您不能将属性附加到在另一个部分文件中声明的成员。

根据您的要求,您可以考虑使用以下选项:

注意: 您可以通过这种方式注册的属性并不是您真正的 class 属性,而是大多数框架,例如 ASP.NET MVC 像使用您的 class 本机属性一样使用它们。

如果你想添加数据注释属性,特别是在 as ASP.NET MVC 项目中,你会发现这种方式很有用。

对于其他不支持 MetadataTypeAttribute 的框架,例如 Windows Forms,您可以简单地使用 AssociatedMetadataTypeTypeDescriptionProvider.

添加支持

该解决方案不限于数据注释属性,您可以使用对您的库和框架有意义的所有类型的属性。

如何定义附加属性?

您可以创建一个元数据 class,其中包含由合适的属性修饰的原始 class 属性,然后用 MetadataType 属性修饰部分 class 并引入原始 class.

的元数据 class

如何查看那些属性的影响?

ASP.NET MVC 等框架使用这些属性,就像它们在您的原始 class 中定义的那样。

您还可以将 AssociatedMetadataTypeTypeDescriptionProvider 注册为其他框架或组件的原始类型的提供者,这些框架或组件可能需要使用 TypeDescriptor 来获取有关您的信息类型。

它们真的是我的class属性吗?

请注意,这样,属性确实不属于你原来的class,但对于大多数框架,如ASP.NET MVCWindows Forms,使用TypeDescriptor 获取有关类型的信息,它们的作用类似于您的 class 原始属性。

所以如果你想使用反射获取属性的属性,你看不到它们,但是如果你使用TypeDescriptor机制,你可以看到它们。

一个例子

哈扎Class:

public partial class Hazaa
{
    public int Shazoo { get; set; }
}

HazaaMetadata Class

[MetadataType(typeof(HazaaMetadata))]
public partial class Hazaa
{
}

public class HazaaMetadata
{
    [DisplayName("Shazoo Name")]
    public int Shazoo { get; set; }
}

ASP.NET MVC 用法

您无需执行任何其他操作即可使 DisplayName 生效,只需使用 Html.Labelfor or Html.DisplayNameFor 即可查看效果。它将 "Shazoo Name" 显示为标签文本。

Windows 表格用法

您的应用程序中的某些地方(例如表单加载、主...)以这种方式注册提供程序:

var provider = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Hazaa));
TypeDescriptor.AddProvider(provider, typeof(Hazaa));

因此,您将看到 PropertyGridDataGridView 使用 "Shazoo Name" 作为 属性 和列标题的标题。

当然你可以使用元数据来做到这一点,如下所示:

public partial class Hazaa : EntityBase
{
    public int Shazoo { get; set; }
}

[MetadataTypeAttribute(typeof(HazaaMetadata))]
public partial class Hazaa : EntityBase
{
    internal sealed class HazaaMetadata
    {
        [SuperCool]
        public int Shazoo { get; set; }
    }
}

确保小数序列化为 2 位小数的最佳方法是 tp:

  1. 使用 XlmAttributeOverides 忽略十进制字段,即不序列化它

var xmlAttributeOverrides = new XmlAttributeOverrides(); var ctrlSumAttributes = new XmlAttributes { XmlIgnore = true }; xmlAttributeOverrides.Add(typeof(Sepa.GroupHeader39), "CtrlSum", ctrlSumAttributes); var ser = new XmlSerializer( typeof( Sepa.Document ), xmlAttributeOverrides);

  1. 使用部分class添加忽略字段的字符串序列化

public 部分 class GroupHeader39 { [XmlElement("CtrlSum")] public 字符串 CtrlSumString { 得到 => CtrlSum.ToString("F2"); set { /* 需要工作 */ } } }

我希望这对解决这个问题的人有所帮助。