带有字符串成员的结构?可以接受无效的默认实例吗? [英] struct with string member? Invalid default instance acceptable?

查看:22
本文介绍了带有字符串成员的结构?可以接受无效的默认实例吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个很好的结构体候选者吗?

Is this a good candidate for a struct?

考虑这个不可变结构示例,其中构造函数验证输入并将验证数据存储为单个路由代码":

Consider this immutable struct example where the constructor validates input and stores the validated data as a single "routing code":

struct RoutingCode
{
  private readonly string routingCode;

  RoutingCode(string prefix, string service, string sender)
  {
    // Validate prefix, service, sender strings
    // ...

    if (isInvalid) throw ArgumentException();

    // 
    this.routingCode = prefix + service + sender;
  }

  // Gets the validated routing code.
  public string Routing
  {
    return this.routingCode;
  }

  public int RoutingLength
  {
    return this.routingCode.Length;
  }
}

这个简化的例子在我看来是使用 struct 而不是 class 的一个很好的候选:

This simplified example appears to me to be a good candidate for using a struct instead of a class:

  • 它是不可变的.
  • 它代表一个奇异值.
  • 实例大小较小.

问题是所有结构都有一个隐式默认构造函数.在此示例中,默认构造函数 RoutingCode() 将实例化一个对象,其中 Routing 属性返回 null—这是无效的路由代码.这与 PointBigInteger 等其他结构不同,其中支持字段包含一个非常合乎逻辑且有效的默认实例零".

The problem is that all structs have an implicit default constructor. In this example, the default constructor RoutingCode() would instantiate an object where the Routing property returns null—which is an invalid routing code. This is a different from other structs such as Point or BigInteger where the backing fields contain a very logical and valid "zero" for default instances.

除了不能确保有效的路由代码之外,如果在默认实例上调用 RoutingLength 属性,则会抛出 NullReferenceException.

In addition to not ensuring a valid routing code, the RoutingLength property throws a NullReferenceException if called on a default instance.

将其保留为 struct 与使其成为 class 的论据是什么?

What are the arguments for keeping this a struct versus making it a class?

推荐答案

你可以轻松解决你的默认值问题:

You can easily solve your default value problems:

struct RoutingCode
{
  private readonly string routingCode;    
  RoutingCode(string prefix, string service, string sender)
  {
    // Validate prefix, service, sender strings
    // ...
    if (isInvalid) throw ArgumentException();
    this.routingCode = prefix + service + sender;
  }

  public string IsValid 
  {
    get { return this.routingCode != null; }
  }

  // Gets the validated routing code.
  public string Routing
  {
    get { return this.routingCode; }
  }

  public int RoutingLength
  {
    get { return this.routingCode == null ? 0 : this.routingCode.Length; }
  }
}

好的,现在所有属性都不会抛出异常,并且您有办法判断该值是否无效.手头的问题是这是否是结构的良好候选者.你说得对,它 (1) 不可变,(2) 小,(3) 逻辑上是一个值.如果您愿意接受可以表示无效值的事实,那么这可能是结构的一个很好的候选者.

OK, now none of the properties throw exceptions and you have a way to tell if the value is invalid. The question at hand is whether or not this is a good candidate for a struct. You are right that it is (1) immutable, (2) small, and (3) logically a value. If you're willing to live with the fact that you can represent an invalid value, then this is probably a good candidate for a struct.

一个更好的问题是:这不是一个类有什么好的理由吗?与其寻找反对使其成为结构的反对意见,不如寻找反对将其设为类的反对意见.

A better question though is: is there a good reason for this not to be a class? Rather than looking for objections to making it a struct, look for objections to making it a class.

这篇关于带有字符串成员的结构?可以接受无效的默认实例吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆