C#结构编译错误
这是一个家庭作业,我们没有学习C#中的结构(现在我正在学习)。所以我去msdn,但我没有找到我的程序的问题... 是的,我不能翻译完全分配给我的本地languange,我不明白编译器的想法。C#结构编译错误
UML我的功课:(我们必须使用它) 接口:IComparable的
- +分母{获得;}:长
- +分母{获得;}:长
- +理性(分子:长,分母:长)
- + GCD(一个:长,b:长):长
- +等于(R:Rationaol):布尔
- ...
而且我们不能实现其他方法或参数。
我用Java编写了这个家庭作业,并且正确地工作。
我有一个很大的问题,我不明白是什么意思以下误差修改:
错误2支持字段的自动实现的属性“Rational.Rational.Denominator”必须控制返回到之前被完全分配呼叫者。考虑从构造函数初始值设定项中调用默认构造函数。
错误3自动实现的属性'Rational.Rational.Numerator'的备份字段必须在控制权返回给调用者之前完全分配。考虑从构造函数初始值设定项中调用默认构造函数。
错误4“这个”对象不能被所有字段之前使用分配给
我的代码: 命名空间合理
{
// (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)
{
...
您可以将this()
添加到您的构造函数中,也可以通过由字段支持的属性替换自动属性。
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;
}
在这里,您分配一个值来支持你的属性自动生成的字段,然后访问实例方法GCD
。
您应该使此方法为静态。
接下来您将再次得到相同的错误,这次是因为您访问了自动属性Numerator
。您可以修复,通过保持汽车性能及增加:this()
的构造器:
public Rational(long num, long den)
:this()
{
这导致在字段中输入您自己的构造函数的代码运行之前被初始化为0
。
另一种方法是切换到字段:从这个代码中除了
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;
}
有几个问题:
1)您使用的是可变的结构。这通常是不好的设计。从你的房产中删除二传手,或将其设为私人。
2)不重写GetHashCode()
要与Equals
一致(或者它只是没有在你的代码片段所示)
3)我建议实施IEquatable<Rational>
。您已经实施了Equals(Rational)
,因此您不需要添加任何其他方法。
4)你的代码很容易产生int溢出。考虑使用BigInteger
而不是long
s。 5)除非你规范你的理性(分母大于0并且除以GCD),否则你会得到数学上相当于不相等的理性。
使您的GCD
函数静态。
它不使用任何实例成员,并且因为它在实例成员设置之前被调用,所以它不能。
你需要调用默认的构造函数这个工作:
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;
}
这里的一个更大的问题是,你有一个可变的结构。这绝不是一个好主意。我想使它:
public long Numerator {get; private set;}
谢谢你,我把作业的UML附在我的问题上。所以我必须以这种方式写...但谢谢你的提示:) – blaces
是的,但这是我第一次在这里大约可变结构:) 如果我从属性中删除setter,我得到了这个问题: 属性或索引'Rational ....'不能被分配给 - 它是只读的 而通过UML,我必须删除setter。但是,如果我将它设置为私有(setter),那么它将会很好:) – blaces
只要搜索可变结构,就会发现很多问题。简短的版本是,在某些情况下,可变结构具有奇怪的语义,人们宁愿避免。公共setter的属性不*,*不好,但任何变异的方法是。 – CodesInChaos
如果你删除了setter,你需要使用我的第三个代码片段,我用场替换了自动属性。然后你需要分配给字段,而不是构造函数中的属性。 – CodesInChaos