【问题标题】:Stipulating that a property is required in a class - compile time规定类中需要一个属性 - 编译时
【发布时间】:2009-02-16 20:11:55
【问题描述】:

有没有办法规定一个类的客户应该为一个类中的一组属性指定一个值。例如(见下面的代码),我可以规定应在编译时指定就业类中的“EmploymentType”属性吗?我知道我可以使用参数化构造函数等。我专门寻找在编译期间输出自定义警告或错误。这可能吗?

public class Employment
{
   public EmploymentType EmploymentType {get; set;}
}

public enum EmploymentType
{
    FullTime = 1,
    PartTime= 2
}

public class Client
{
    Employment e = new Employment();
// if i build the above code, i should get a error or warning saying you should specify value for EmploymentType
}

【问题讨论】:

    标签: c# .net compiler-construction clr


    【解决方案1】:

    正如 cmsjr 所说,您需要做的是:

    public class Employment
    {
        public Employment(EmploymentType employmentType)
        {
            this.EmploymentType = employmentType;
        }
    
        public EmploymentType EmploymentType { get; set; }
    }
    

    这将强制调用者在创建时像这样传递值:

    Employment e = new Employment(EmploymentType.FullTime);
    

    在您需要有默认构造函数(如序列化)但仍想强制执行规则的情况下,您将需要某种状态验证。例如,每当您尝试对就业类执行操作时,您都可以让它检查如下的有效状态:

    public EmploymentType? EmploymentType { get; set; } // Nullable Type
    
    public void PerformAction()
    {
        if(this.Validate())
            // Perform action
    }
    protected bool Validate()
    {
        if(!EmploymentType.HasValue)
            throw new InvalidOperationException("EmploymentType must be set.");
    }
    

    如果您正在寻找抛出自定义编译器警告,这是不可能的。我在这里问了类似的问题Custom Compiler Warnings

    【讨论】:

    • 是的。我想知道是否有办法根据状态触发自定义错误/警告。好像是不可能的。您指向自定义编译器警告的链接很有帮助。
    【解决方案2】:

    您可以通过不使用默认构造函数来实现您想要做的事情,而是定义一个将就业类型作为参数的构造函数。如果有人试图使用无参数构造函数来实例化类,他们会得到一个编译错误。

    编辑代码示例

      public Employment(EmploymentType eType)
        {
          this.EmploymentType = eType;
        }
    

    【讨论】:

    • 是的。你对此表示敬意。但是如果在需要默认构造函数的情况下怎么办。喜欢序列化?那么客户端可以在参数化构造函数中选择默认值。
    • 如果你必须有一个公共的默认构造函数,我不知道有什么方法可以导致编译时错误,什么是运行时状态。
    【解决方案3】:

    OO 原则规定对象永远不应处于无效状态。所以这应该是一个构造函数参数。

    没有办法在编译时指出一个属性是必需的。

    【讨论】:

      【解决方案4】:

      您在原始帖子中提到您已经知道使用构造函数执行此操作,这绝对是正确的方法。我不相信会有任何方式来做你想做的事,即使是属性(这通常是你操作编译器警告等的方式)。由于可以创建对象,然后将其传递给另一个方法来设置参数,因此不一定像“客户端必须指定值”那样明显。

      您可以尝试创建自定义 FxCop 或 VSTS 静态分析规则,但我认为仅使用 C# 编译器无法做到这一点。

      【讨论】:

        【解决方案5】:
        Interface Icontrol
         ' Declare an interface.
         Property MustHave() As String
        
        End Interface
        

        然后在你的用户控件中包含

         Public Class mycontrol
         Inherits System.Web.UI.UserControl
         Implements Icontrol
        

        它使这个属性成为必需的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-01
          相关资源
          最近更新 更多