简体   繁体   English

C#struct编译错误

[英]C# struct compile errors

This is a homework, and we don't learn the structs in C# (and I am learn now). 这是一个功课,我们不学习C#中的结构(我现在正在学习)。 So I go to the msdn, but I don't find what my program's problem... Yes, and I can't translate fully assigned to my native languange, and I don't understadn what the compiler thinks. 所以我去了msdn,但是我找不到我的程序的问题...是的,我无法完全分配给我的本地语言,而且我不会理解编译器的想法。

UML of my homework: (we must use it) Interface: IComparable 我的作业的UML :(我们必须使用它)接口:IComparable

  • +Numerator{get;}:long +分母{获得;}:长
  • +Denominator{get;}:long +分母{获得;}:长
  • +Rational(numerator:long, denominator:long) +理性(分子:长,分母:长)
  • +GCD(a:long, b:long):long + GCD(a:长,b:长):长
  • +Equals(r:Rationaol):bool +等于(R:Rationaol):布尔
  • ... ...

And we mustn't implement another methods or params. 我们不能实施其他方法或参数。

I write this homework in Java with classes and that work correctly. 我用Java编写这个功课,并且正常工作。

I have a big problem, I don't understand what mean the following erros: 我有一个大问题,我不明白以下错误是什么意思:

Error 2 Backing field for automatically implemented property 'Rational.Rational.Denominator' must be fully assigned before control is returned to the caller. 错误2在将控制权返回给调用者之前,必须完全分配自动实现的属性“Rational.Rational.Denominator”的后备字段。 Consider calling the default constructor from a constructor initializer. 考虑从构造函数初始化程序中调用默认构造函数。

Error 3 Backing field for automatically implemented property 'Rational.Rational.Numerator' must be fully assigned before control is returned to the caller. 错误3必须完全分配自动实现的属性“Rational.Rational.Numerator”的备份字段,然后才能将控制权返回给调用者。 Consider calling the default constructor from a constructor initializer. 考虑从构造函数初始化程序中调用默认构造函数。

Error 4 The 'this' object cannot be used before all of its fields are assigned to 错误4在分配所有字段之前,不能使用“this”对象

my code: namespace Rational 我的代码:命名空间Rational

{
    //       (Rational is underline)     here the 2 and 3 error
    public struct Rational : IComparable<Rational>
    {
        public long Numerator { get; set; }
        public long Denominator { get; set; }

        public Rational(long num, long den)
        {
             // and here (GCD is underline) the 4. error
            long simple = GCD(num, den);
            this.Numerator = num/simple;
            this.Denominator = den/simple;
        }

        public long GCD(long a, long b)
        {
            long c = Math.Abs(a);
            long d = Math.Abs(b);
            if (d == 0) return c;
            return GCD(d, c % d);
        }

        public override string ToString()
        {
            if (Denominator==1)
            {
                return Numerator + "";
            }
            return Numerator+"/"+Denominator;
        }

        public override bool Equals(object obj)
        {
            bool result = false;
            if (obj is Rational)
            {
                Rational r = (Rational)obj;
                result = this.Equals(r);
            }
            return result;            
        }

        public bool Equals(Rational r)
        {
            if ((object)r ==null)
            {
                return false;
            }
            return this.Denominator == r.Denominator && this.Numerator == r.Numerator;
        }

        public int CompareTo(Rational other)
        {
      ...

You can either add a this() to your constructor, or replace the auto-properties by properties backed by a field. 您可以将this()添加到构造函数中,也可以使用字段支持的属性替换auto-properties。

 public Rational(long num, long den)
 {
         // and here (GCD is underline) the 4. error
        long simple = GCD(num, den);
        this.Numerator = num;
        this.Denominator = den;
 }

Here you access the instance method GCD before you assigned a value to the auto generated fields backing your properties. 在为支持属性的自动生成字段分配值之前,可以在此处访问实例方法GCD

You should make this method static. 您应该将此方法设为静态。

Next you will get the same error again, this time because you access the auto property Numerator . 接下来,您将再次收到相同的错误,这次是因为您访问了自动属性Numerator You can fix that by keeping the auto properties and adding :this() to the constructor: 您可以通过保留自动属性并将:this()添加到构造函数来解决此问题:

 public Rational(long num, long den)
   :this()
 {

That results in the fields being initialized to 0 before your own constructor code runs. 这导致在您自己的构造函数代码运行之前将字段初始化为0

The alternative is switching to fields: 替代方案是切换到字段:

public struct Rational : IComparable<Rational>
{
    private long _numerator;
    private long _denominator;

    public long Numerator { get{return _numerator;}; set{_numerator=value;} }
    public long Denominator{ get{return denominator;}; set{_denominator=value;} }

    public Rational(long num, long den)
    {
         // and here (GCD is underline) the 4. error
        long simple = GCD(num, den);
        this._numerator = num;
        this._denominator = den;
    }

Apart from this your code has few more issues: 除此之外,您的代码还有更多问题:

1) You're using a mutable struct. 1)您正在使用可变结构。 That's usually bad design. 这通常是糟糕的设计。 Remove the setter from your properties or make it private. 从您的属性中删除setter或将其设为私有。

2) You don't override GetHashCode() to be consistent with Equals (or it's just not shown in your code excerpt) 2)你没有覆盖GetHashCode()以与Equals一致(或者它没有在你的代码摘录中显示)

3) I recommend implementing IEquatable<Rational> . 3)我建议实现IEquatable<Rational> You already implemented Equals(Rational) , so you don't need to add any additional methods. 您已经实现了Equals(Rational) ,因此您无需添加任何其他方法。

4) Your code produces int overflows very easily. 4)您的代码很容易产生int溢出。 Consider using BigInteger s instead of long s. 考虑使用BigInteger而不是long

5) Unless you normalize your rational (denominator >0 and dividing both by the GCD) you get mathematically equivalent rationals that don't compare as equal. 5)除非你将你的理性归一化(分母> 0并且用GCD除以),否则你得到的数学上等价的理性数不能相等。

You need to call the default constructor for this to work: 您需要调用默认构造函数才能使其工作:

public Rational(long num, long den) : this()
{
    // and here (GCD is underline) the 4. error
    long simple = GCD(num, den);
    this.Numerator = num;
    this.Denominator = den;
}

A bigger problem here is that you have a mutable struct. 这里一个更大的问题是你有一个可变的结构。 This is never a good idea. 这绝不是一个好主意。 I would make it: 我会成功的:

public long Numerator {get; private set;}

我在Rational的构造函数中注意到你正在调用GCD并将结果存储为simple ,但是你不使用结果。

Make your GCD function static. 使您的GCD功能保持静态。

It doesn't use any instance members, and because it's called before instance members are set, it can't. 它不使用任何实例成员,并且因为它在实例成员设置之前被调用,所以它不能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM