Nic*_*ner 79 c# const parameter-passing readonly
我正在寻找与Java相当的C#final.它存在吗?
C#是否包含以下内容:
public Foo(final int bar);
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,bar是一个只读变量,不能更改Foo().有没有办法在C#中做到这一点?
比如,也许我还有很长的方法,将与其合作x,y和z一些对象(整数)的坐标.我想绝对肯定该函数不会以任何方式改变这些值,从而破坏数据.因此,我想宣读它们.
public Foo(int x, int y, int z) {
// do stuff
x++; // oops. This corrupts the data. Can this be caught at compile time?
// do more stuff, assuming x is still the original value.
}
Run Code Online (Sandbox Code Playgroud)
Cor*_*old 59
不幸的是你无法在C#中做到这一点.
该const关键字只能用于局部变量和字段.
该readonly关键字只能用于字段.
注意:Java语言还支持为方法提供最终参数.此功能在C#中不存在.
来自http://www.25hoursaday.com/CsharpVsJava.html
Max*_*Max 24
现在可以在C#7.2版中实现:
您可以in在方法签名中使用关键字.MSDN文档.
该in关键字应在指定方法的参数之前加入.
例如,C#7.2中的有效方法:
public long Add(in long x, in long y)
{
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
虽然不允许以下内容:
public long Add(in long x, in long y)
{
x = 10; // It is not allowed to modify an in-argument.
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
尝试修改时会显示以下错误,x或者y因为它们标记为in:
无法分配变量'in long',因为它是一个只读变量
用in手段标记参数:
此方法不会修改用作此参数的参数的值.
我将从这int部分开始. int是一种值类型,在.Net中,这意味着您真正在处理副本.这是一个非常奇怪的设计约束,告诉方法"你可以得到这个值的副本.这是你的副本,而不是我的副本;我永远不会再看到它了.但你无法改变副本." 在方法调用中隐含了复制此值是可以的,否则我们无法安全地调用该方法.如果该方法需要原始文件,请将其留给实施者进行复制以保存原文.要么给方法赋值,要么不给方法赋值.不要在两者之间全力以赴.
让我们继续讨论类型.现在它有点令人困惑.你的意思是一个恒定的引用,其中引用本身不能被更改,或者一个完全锁定,不可更改的对象?如果是前者,默认情况下.Net中的引用是按值传递的.也就是说,您获得了参考文献的副本.因此,我们与价值类型的情况基本相同.如果实现者需要原始引用,他们可以自己保留它.
这只是给我们留下了常量(锁定/不可变)对象.从运行时的角度来看,这似乎没什么问题,但编译器如何强制执行呢?由于属性和方法都有副作用,因此基本上只限于只读字段访问.这样的对象不太可能非常有趣.
小智 8
答案:C#没有像C++那样的const功能.
我同意Bennett Dill的观点.
const关键字非常有用.在这个例子中,你使用了一个int,人们不明白你的观点.但是,为什么如果你的参数是一个用户庞大而复杂的对象,在该函数内部无法更改?这是使用const关键字:参数不能在该方法内部进行更改,因为[此处无论什么原因]对该方法无关紧要.Const关键字非常强大,我真的很想念它在C#中.
这是一个简短而又甜蜜的答案,可能会得到很多票数.我没有阅读所有的帖子和评论,所以请原谅我,如果以前曾建议的那样.
为什么不把你的参数传递给一个将它们公开为不可变的对象,然后在你的方法中使用该对象?
我意识到这可能是一个非常明显的工作,已经考虑过,OP试图通过提出这个问题来避免这样做,但我觉得它应该在这里,不过不...
祝好运 :-)
为您的类创建一个仅具有只读属性访问器的接口。然后让您的参数属于该接口,而不是类本身。例:
public interface IExample
{
int ReadonlyValue { get; }
}
public class Example : IExample
{
public int Value { get; set; }
public int ReadonlyValue { get { return this.Value; } }
}
public void Foo(IExample example)
{
// Now only has access to the get accessors for the properties
}
Run Code Online (Sandbox Code Playgroud)
对于结构,创建一个通用的const包装器。
public struct Const<T>
{
public T Value { get; private set; }
public Const(T value)
{
this.Value = value;
}
}
public Foo(Const<float> X, Const<float> Y, Const<float> Z)
{
// Can only read these values
}
Run Code Online (Sandbox Code Playgroud)
但是,值得注意的是,作为方法的编写者,您想要完成关于结构的要求,这很奇怪,您应该期望知道该方法的工作。它不会影响传入的值以在方法中修改它们,因此您唯一需要考虑的是确保自己在编写的方法中表现得很好。在强制执行const和其他此类规则方面,警惕性和整洁的代码是关键。