使用静态类型成员以确保非静态类中的类型安全

时间:2018-11-14 10:18:46

标签: c#

我有一个定义如下的静态类:

public static class JobStatus
{ 
    public const string Completed = "Completed";
    public const string Failed = "Failed";
    public const string Stopped = "Stopped";
}

(这实际上是一个外部库,因此无法更改)

在我的非静态类中,我希望该类的成员确保您只能声明该“类型”

public class JobOutput
{
    public string Output { get; set; }

    public string OutputError { get; set; }

    public JobStatus JobStatus { get; set; }
}

错误:'JobStatus':静态类型不能用作返回类型/'JobStatus':静态类型不能用作参数

Yeye,我知道您的眼睛在流血,但我希望您明白了-我如何确保和实现JobStatus属性的类型安全形式?

2 个答案:

答案 0 :(得分:1)

您不能这样做,因为所有JobStatus都包含一些持有字符串的成员。因此,您还必须将JobStatus属性定义为字符串。

对于字符串没有编译时的安全性,它本来可以是枚举。

您可以将方法SetJobStatus(string status)添加到JobOutput类中,并将JobStatus的setter设为私有。然后,在该方法中,检查(使用反射)在静态类status的公共const字段之一中是否存在JobStatus字符串。或者,您可以在设置器中实现相同的功能。

有关如何执行此操作的信息,请参见How can I get all constants of a type by reflection?。但这不是编译时的安全,而是运行时。

答案 1 :(得分:1)

您可以包装JobStatus使其成为“类型安全”,但看起来有些过分了:

public sealed class JobStatusWrapper
{
     public static readonly JobStatusWrapper Completed 
         = new JobStatusWrapper(JobStatus.Completed);

     public static readonly JobStatusWrapper Failed
         = new JobStatusWrapper(JobStatus.Failed);

     public static readonly JobStatusWrapper Stopped
         = new JobStatusWrapper(JobStatus.Stopped);

     private readonly string description;
     private JobStatusWrapper(string description) {
         Debug.Assert(!string.IsNullOrEmpty(description));
         this.description = description; }

     public static implicit operator string(JobStatusWrapper status)
         => status.description;
}

现在您将使用它:

public class JobOutput
{
    //...
    public JobStatusWrapper JobStatus { get; set; }
}

并且没有办法传递或获取没有JobStatusWrapper中定义的基础值之一的JobStatusnull除外)。同样,隐式运算符使包装器在JobStatus选项可用的任何地方都可用。