具有new和get integer的C#构造函数

具有new和get integer的C#构造函数,c#,C#,这是Unity 5.5.0上的一个结构。我对c#非常陌生,不太了解属性和结构 这会在This.X期间出现分配错误 我假设您不能更改结构上的值,关键字this指的是结构的属性 在将控件返回给调用方之前,必须完全分配自动实现的属性“Point.X”的支持字段。考虑从构造函数初始化器调用默认构造函数。(CS0843)(装配CSharp)[LN 15] 在将“this”对象的所有字段分配给(CS0188)(程序集CSharp)[LN 16]之前,不能使用该对象 这是C#的一些版本的一个奇怪之处;编译器有

这是Unity 5.5.0上的一个结构。我对c#非常陌生,不太了解属性和结构

这会在
This.X
期间出现分配错误

我假设您不能更改结构上的值,关键字this指的是结构的属性

在将控件返回给调用方之前,必须完全分配自动实现的属性“Point.X”的支持字段。考虑从构造函数初始化器调用默认构造函数。(CS0843)(装配CSharp)[LN 15]

在将“this”对象的所有字段分配给(CS0188)(程序集CSharp)[LN 16]之前,不能使用该对象


这是C#的一些版本的一个奇怪之处;编译器有时无法正确地检测结构是否已通过构造函数在所有代码路径上完全初始化

解决办法是说

public Point(int x, int y) : this()  // default initialization
{ 
  this.X = x;
  this.Y = y;
}
它告诉编译器“在构造函数中初始化字段之前,字段已初始化为其默认值”

当我们使用C#3时,这是语言设计的一点失败;这绝对不是你必须要做的。很抱歉

既然我引起了你们的注意,让我们谈谈你们提出的另一点:

我假设您不能更改结构上的值

可以更改结构上的值,但不应更改。结构应为:

  • 小的
  • 逻辑价值
  • 不变的
因此,我的建议是将setter设置为private(使用
private set;

您创建了一个可变点结构,这是一个糟糕的做法。创建一个不可变的点结构,并将其视为不可变的数学对象,而不是变量集合

此外:

关键字this指的是结构的属性

关键字
this
是保存结构实例值的变量的别名。这是微妙的;让我给你举个例子。如果我们说:

Point a = new Point(1, 2);
这意味着:

  • 创建一个大小为一个点的新临时存储变量
  • 调用双参数构造函数,使
    this
    成为该临时存储变量的别名,并将1和2复制到形式参数x和y中
  • 构造函数返回后,将临时变量中的值复制到变量
    a
现在,您可能会注意到,这样做似乎更有效率:

  • 调用双参数构造函数,使
    this
    成为
    a
    的别名,依此类推
这样会更有效率;这就是所谓的拷贝省略优化,C#在知道用户不可能注意到差异时就这样做了。(挑战:构造一个C#程序,用户可以在其中确定是否使用了复制省略;C#不会在这样的程序中复制省略!)

同样,如果您当时这样做:

struct Point
{
   ... constructors, whatever ...
   public double DistanceFromOrigin()
   {
     return Math.Sqrt(this.X * this.X + this.Y * this.Y);
   }
当您调用
a.DistanceFromOrigin()
时,
将成为
a
的别名;它们是同一个变量,只是有两个不同的名称

这不是引用类型的工作方式。在引用类型中,
是引用的副本。在值类型中,
是变量的别名


这些都是细微之处。

可能重复尝试将
公共点(int x,int y)
更改为
公共点(int x,int y):this()
欢迎使用堆栈溢出。希望上面的链接能帮助回答您的问题,并为您提供解决问题所需的想法。请注意,我是通过将错误消息复制到google搜索中找到此链接的。这通常是解决此类问题的一种非常快速的方法。在Eric发布了一个挑战但仍然没有提出解决方案的13分钟后8 |一定很难…@vc74:没那么难。试试看!vc74认为捕获与此有关的想法是好的。例如:
struct S{private int x;private int y;public S(int x,int y,Action a){this.x=x;a();this.y=y;}public override string ToString()=>(y>0.ToString();}
现在假设我们有
S=default(S);s=新的s(1,2,()=>{});s=新的s(3,4,()=>Console.WriteLine(s)现在我们可以判断副本是否被省略。如果是,并且对
s
的第三个赋值是直接变异
s
,那么
y
2
,因此这将打印
True
。如果副本没有被省略,那么
y
在temp中仍然是零。@vc74:你有没有在main中有一个带有未省略的try块在这种情况下,会发生什么是实现定义的。当出现未捕获的异常时,允许程序执行任何操作,“运行最终块”包含在“任何操作”中,就像“不运行最终块”一样@vc74:不,你没有明白我说的。不管最后在程序中的什么位置尝试。重要的是是否捕捉到异常!如果从未捕捉到异常,则运行时可以做任何事情。它可以立即终止进程,启动调试器,还可以打电话给Microsoft总部描述异常崩溃,它可以运行finally blocks,它不能运行finally blocks,它可以做任何你可以编写程序来做的事情。如果你不喜欢这样,那么就捕获抛出的每个异常。未捕获的异常是纯粹的邪恶。
struct Point
{
   ... constructors, whatever ...
   public double DistanceFromOrigin()
   {
     return Math.Sqrt(this.X * this.X + this.Y * this.Y);
   }