使用在C#中传递null的选项将枚举传递给函数的干净方法

时间:2010-02-18 16:35:54

标签: c# enums null

我有一个代表物理结构的物体(如电线杆),它接触一堆其他物体(杆子上的电线)。其他对象具有表示为枚举的一组特征(状态,大小,电压,相位等)。我想编写一个通用函数来计算有多少电线匹配任何或所有特性。

如果枚举是一流的对象,我想我只想写下这个:

class Wire
{
    public EStatus Status { get; set; }
    public ESize Size { get; set; }
    public EVoltage Voltage { get; set; }
    public EPhase Phase { get; set; }
}

int CountWires(EStatus status, ESize size, EVoltage voltage, EPhase phase)
{
    int count = 0;
    foreach (Wire wire in _connectedWires)
    {
        if (status != null && wire.Status != status) continue;
        if (size != null && wire.Size != size) continue;
        //...
        ++count;
    }
    return count;
}

......并且可以将其称为只计算任何电压和相位的新的大电线:

CountWires(EStatus.New, ESize.Large, null, null);

...但当然这会导致cannot convert from '<null>' to 'EVoltage'错误。

我们过去通过向枚举本身添加“任意”值并对其进行检查来解决这个问题,但是如果我们做了类似的事情,那么我们必须过滤掉用户列表中的所有可能值“任何”。所以我想避免这种情况。

我以为我会把它扔给社区,看看是否有人有任何想法,通过干净的界面和易于阅读的调用代码来实现这一目标。我有自己的答案,我会加入讨论。

6 个答案:

答案 0 :(得分:10)

或者只使用可空类型。

int CountWires(EStatus? status, ESize? size, EVoltage? voltage, EPhase? phase)
{
    int count = 0;
    foreach (Wire wire in _connectedWires)
    {
        if (status.HasValue && wire.Status != status.Value) continue;
        if (size.HasValue && wire.Size != size.Value) continue;
        ...
        ++count;
    }
    return count;
}

答案 1 :(得分:4)

你尝试过正常的可空吗?随着?语法非常简洁(而C#内置了隐式运算符)

CountWires(EStatus? status, ESize? size, EVoltage? voltage, EPhase? phase)

使用非常简单

if (status.HasValue)
  stats.Value

答案 2 :(得分:2)

你不能只使用

CountWires(EStatus? status, ESize? size, EVoltage? voltage, EPhase? phase)

您必须在CountWires函数的开头执行类似的操作,以确保代码运行时状态不为空

status = status ?? EStatus.DefaultValue;

或者你的代码需要运行的任何值......在你的情况下,你实际上不想要默认值,而是将它们保留为空

答案 3 :(得分:2)

怎么样

CountWires(EStatus? status, ESize? size, EVoltage? voltage, EPhase? phase)

答案 4 :(得分:0)

我正在尝试创建一个NullableEnum类:

class NullableEnum<T> where T : struct
{
    T _value;
    NullableEnum(T value) { _value = value; }
    public T Value { get { return _value; } }
}

...除了持有一个值并且是一流的对象之外别无他法。然后我会有这个签名:

CountWires(NullableEnum<EStatus> status,
           NullableEnum<ESize> size,
           NullableEnum<EVoltage> voltage,
           NullableEnum<EPhase> phase)

...但是调用代码必须如下所示:

CountWires(NullableEnum<EStatus>(EStatus.New), NullableEnum<ESize>(ESize.Large), null, null);

......这有点麻烦。

答案 5 :(得分:0)

同样,Jon Skeet先生创建了一个名为Unconstrained Melody的漂亮的类型约束枚举库。