如何将属性添加到基类的属性

Mr *_*ell 43 c#

我有几个模型类,如下:

public class MyModelBase
{
    public string Name { get; set; }
}

public class MyModel : MyModelBase
{
    public string SomeOtherProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

MyModel如何在Name属性中添加[Required]属性?

Jus*_*ner 40

将父类中的属性声明为virtual:

public class MyModelBase
{
    public virtual string Name { get; set; }
}

public class MyModel : MyModelBase
{
    [Required]
    public override string Name { get; set; }

    public string SomeOtherProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

或者你可以使用MetadataType来处理验证(只要你在谈论DataAnnotations ......否则你会被上面的例子所困扰):

class MyModelMetadata
{
    [Required]
    public string Name { get; set; }

    public string SomeOtherProperty { get; set; }
}

[MetadataType(typeof(MyModelMetadata))]
public class MyModel : MyModelBase
{
    public string SomeOtherProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 根据[MSDN](https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx)**MyModel**应该是部分的. (4认同)
  • 请注意**使用新的自动属性**覆盖自动属性**会导致**两倍于支持字段**(即〜双实例大小).更可怕的是,您可能无意中**丢失了基类的字段初始化程序**中的数据!(数据位于基础支持字段中,但覆盖实现仅查看其_own_支持字段.)请参阅Justin Minnaar的答案以获得更好的覆盖方式. (3认同)
  • 如果您不想失去其他行为,则可以采用这种方法。+1 (2认同)

Kev*_*vin 35

尝试使用元数据类.它是一个单独的类,使用允许您间接向模型类添加数据注释的属性进行引用.

例如

[MetadataType(typeof(MyModelMetadata))]
public class MyModel : MyModelBase {
  ... /* the current model code */
}


internal class MyModelMetadata {
    [Required]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • [MSDN](https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx)说**MyModel**应该是部分的. (3认同)
  • 我的猜测是,这仅适用于DataAnnotations命名空间中的属性,因此不是通用解决方案。 (2认同)

小智 16

我注意到这些答案中没有一个实际上正确地调用了基本Name属性.覆盖应该写如下所示,以便您没有新属性的单独值.

public class MyModelBase
{
    public virtual string Name { get; set; }
}

public class MyModel : MyModelBase
{
    [Required]
    public override string Name { get { return base.Name; } set { base.Name = value; }

    public string SomeOtherProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 我看不到,为什么有必要。如果您说的是正确的,则此代码不起作用,但仍然有效:http://csharppad.com/gist/c5db27fb3b90f961a2da。我猜想,编译器会自动处理覆盖的自动属性。 (2认同)
  • @Spook我认为只有当您在基类中有一些自定义实现(例如setter中的RaisePropertyChanged)时才有必要。如果仅在子类中使用自动属性,则不会调用基类中的 getter/setter。 (2认同)