C# 在结构上隐藏无参数构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/535328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:10:09  来源:igfitidea点击:

hide parameterless constructor on struct

c#.netstruct

提问by ChrisCa

Is it possible to hide the parameterless constructor from a user in c#

是否可以在 c# 中对用户隐藏无参数构造函数

I want to force them to always use the constructor with parameters

我想强制他们总是使用带参数的构造函数

e.g. this Position class

例如这个职位类

public struct Position
{
    private readonly int _xposn;
    private readonly int _yposn;

    public int Xposn
    {
        get { return _xposn; }
    }

    public int Yposn
    {
        get { return _yposn; }
    }

    public Position(int xposn, int yposn)
    {
        _xposn = xposn;
        _yposn = yposn;
    }        
}

I only want users to be able to new up a Position by specifying the x and y coordinates

我只希望用户能够通过指定 x 和 y 坐标来新建一个位置

However, the parameterless constructor is ALWAYS availiable

但是,无参数构造函数始终可用

I cannot make it private. Or even define it as public

我不能把它设为私有。甚至将其定义为公共

I have read this Why can't I define a default constructor for a struct in .NET?

我已经阅读了 为什么我不能为 .NET 中的结构定义默认构造函数?

but it doesnt really help

但它并没有真正帮助

If this is not possible - what is the best way to detect if the Position I am being passed has values?

如果这是不可能的 - 检测我传递的位置是否具有值的最佳方法是什么?

Explicity checking each property field? Is there a slicker way?

明确检查每个属性字段?有更巧妙的方法吗?

thanks

谢谢

采纳答案by Jon Skeet

No, you can't do this. As you said, similar questionhas been asked before - and I thought the answer was fairly clear that you couldn't do it.

不,你不能这样做。正如您所说,之前也有人问过类似的问题-我认为答案很清楚,您不能这样做。

You cancreate a private parameterless constructor for a struct, but not in C#. However, even if you do that it doesn't really help - because you can easily work around it:

可以为 struct 创建私有无参数构造函数,但不能在 C# 中创建。但是,即使您这样做也无济于事 - 因为您可以轻松解决它:

MyStruct[] tmp = new MyStruct[1];
MyStruct gotcha = tmp[0];

That will be the default value of MyStruct - the "all zeroes" value - without ever calling a constructor.

这将是 MyStruct 的默认值 - “全零”值 - 无需调用构造函数。

You could easily add a Validate method to your struct and call that each time you received one as a parameter, admittedly.

诚然,您可以轻松地将 Validate 方法添加到您的结构中,并在每次收到一个作为参数时调用该方法。

回答by Spence

Well a struct is literally a declaration of how the memory will sit.

好吧,结构实际上是内存将如何放置的声明。

Even when you use an object, the objects pointer IS declared, regardless of whether it's null.

即使当您使用一个对象时,对象指针也会被声明,无论它是否为空。

The reason that you can't hide the constructor is because the struct demands that the CLR can create it as internally it must do this.

不能隐藏构造函数的原因是结构要求 CLR 可以在内部创建它,因为它必须这样做。

You could convert this struct into an object to achieve this task. Or use static analysis to ensure it's intialized before you use it?

您可以将此结构转换为对象来完成此任务。或者在使用之前使用静态分析来确保它已初始化?

struct point
{
   int xpos;
   int ypos;
}

Have a google for immutable objects, this appears to be what your after. I believe that they are looking to add this feature (but not in C# 4) to the language itself, because it is a common requirement. Is there a specific need for a struct here?

有一个不可变对象的谷歌,这似乎是你想要的。我相信他们希望将此功能(但不在 C# 4 中)添加到语言本身,因为这是一个常见的要求。这里是否有特定的结构需求?

回答by DavidN

Nope can't hide it. Structs cannot redefine zero arg constructor, so therefore its visibility can't be redefined.

不可以隐藏它。结构不能重新定义零参数构造函数,因此它的可见性不能被重新定义。

回答by Ryan

You cannot make a struct with a private parameter-less constructor or even declare a parameter-less constructor. You would have to change it to a class. Structs are not allow to declare a parameterless constructor.

您不能使用私有无参数构造函数创建结构,甚至不能声明无参数构造函数。您必须将其更改为一个类。结构不允许声明无参数构造函数。

From the Structs Tutorialon MSDN:

来自MSDN 上的结构教程

Structs can declare constructors, but they must take parameters. It is an error to declare a default (parameterless) constructor for a struct. Struct members cannot have initializers. A default constructor is always provided to initialize the struct members to their default values.

结构可以声明构造函数,但它们必须带参数。为结构声明默认(无参数)构造函数是错误的。结构成员不能有初始值设定项。始终提供默认构造函数以将结构成员初始化为其默认值。

From the C# specificationon MSDN:

来自MSDN 上的C# 规范

11.3 Class and struct differences

11.3 类和结构体的区别

Structs differ from classes in several important ways:

结构在几个重要方面与类不同:

  • Structs are value types (Section 11.3.1).
  • All struct types implicitly inherit from the class System.ValueType (Section 11.3.2). Assignment to a variable of a struct type creates a copy of the value being assigned (Section 11.3.3).
  • The default value of a struct is the value produced by setting all value type fields to their default value and all reference type fields to null (Section 11.3.4). Boxing and unboxing operations are used to convert between a struct type and object (Section 11.3.5).
  • The meaning of this is different for structs (Section 11.3.6).
  • Instance field declarations for a struct are not permitted to include variable initializers (Section 11.3.7).
  • A struct is not permitted to declare a parameterless instance constructor (Section 11.3.8).
  • A struct is not permitted to declare a destructor (Section 11.3.9).
  • 结构是值类型(第 11.3.1 节)。
  • 所有结构类型都隐式继承自 System.ValueType 类(第 11.3.2 节)。对结构类型的变量赋值会创建所赋值值的副本(第 11.3.3 节)。
  • 结构体的默认值是通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为 null(第 11.3.4 节)而产生的值。装箱和拆箱操作用于在结构类型和对象之间进行转换(第 11.3.5 节)。
  • 这对于结构体的含义是不同的(第 11.3.6 节)。
  • 结构体的实例字段声明不允许包含变量初始值设定项(第 11.3.7 节)。
  • 不允许 struct 声明无参数的实例构造函数(第 11.3.8 节)。
  • 不允许结构体声明析构函数(第 11.3.9 节)。