我理解不变性是什么,以及String .NET类是如何特殊的.不变性使得它的行为类似于值类型,即使它是引用类型.得到它了.C#参考强调了这一点(参见字符串(C#参考),我强调的重点:
字符串是不可变的 - 在创建对象后,字符串对象的内容无法更改,尽管语法使其看起来好像可以执行此操作.例如,当您编写此代码时,编译器实际上会创建一个新的字符串对象来保存新的字符序列,并将该新对象分配给b.然后字符串"h"有资格进行垃圾回收.
作为一名自学成才的程序员,我不熟悉垃圾收集器和内存泄漏以及指针和内容.这就是我问这个问题的原因.C#编译器如何自动创建新的字符串对象并放弃旧的字符串对象的描述使得它看起来像一堆内存可能会被废弃的字符串内容用尽.许多对象都有处置方法或析构函数,因此即使是自动CLR垃圾收集器也知道何时以及如何在不再需要的对象之后进行清理.字符串没有这样的东西.我想看看如果创建一个程序实际上会发生什么,这样我就可以为自己和其他人说明创建并立即放弃字符串对象会占用大量内存.
这是程序:
class Program {
static void Main(string[] args)
{
Console.ReadKey();
int megaByte = (int)Math.Pow(1024, 2);
string[] hog = new string[2048];
char c;
for (int i = 0; i < 2048; i++)
{
c = Convert.ToChar(i);
Console.WriteLine("Generating iteration {0} (char = '{1}')", i, c);
hog[i] = new string(c, megaByte);
if ((i + 1) % 256 == 0) {
for (int j = (i - 255); j <= i; j++) { hog[j] = …
Run Code Online (Sandbox Code Playgroud) 是否可以在C#中添加文字代码块作为事件处理程序?就像是:
Timer t = new Timer(1000);
t.Elapsed += new ElapsedEventHandler({ Console.WriteLine("Tick"); });
Run Code Online (Sandbox Code Playgroud)
您可以在PowerShell中执行此操作,因此我认为在C#中可能还有某种方法可以执行此操作.
在Windows窗体应用程序中,有些事情我希望在不同表单上使用相同类型的各种控件来始终对某些事件执行操作.例如,我想单击一个TextBox类型的DataGridViewCell,并且不能只读取自动进入编辑模式.简单的事件处理程序代码,在这种情况下,在一个名为DataGridView的表单上dgvParms
,是:
private void dgvParms_CellClick(object sender, DataGridViewCellEventArgs e) {
DataGridViewCell c = dgvParms[e.ColumnIndex, e.RowIndex];
if (!c.ReadOnly && c is DataGridViewTextBoxCell) {
dgvParms.CurrentCell = c;
dgvParms.BeginEdit(true);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以轻松地将此方法移动到静态类,比如说CommonEvents
,然后在我的各个表单的Load
处理程序上将静态方法定义分配给相应的DataGridViews的CellClick事件
this.dgvParms.CellClick += CommonEvents.dgvEditOnCellClick;
Run Code Online (Sandbox Code Playgroud)
这是可接受的还是良好的做法?或者它是否优先保留事件处理程序逻辑与每个消费形式的代码?我当然可以通过定义本地事件处理程序然后调用公共方法来做两件事(但是多余的),例如
this.dgvParms.CellClick += (a, b) => CommonEvents.dgvEditOnCellClick(a, b);
Run Code Online (Sandbox Code Playgroud) Go具有任意大小和精度的无类型精确数字常量。该规范要求所有编译器支持至少256位的整数,并且至少浮动272位(尾数为256位,指数为16位)。因此,要求编译器忠实准确地表示如下表达式:
const (
PI = 3.1415926535897932384626433832795028841971
Prime256 = 84028154888444252871881479176271707868370175636848156449781508641811196133203
)
Run Code Online (Sandbox Code Playgroud)
这很有趣......,但我无法找到任何方式实际使用任何这种持续超过64位的具体类型的最大精度int64
,uint64
,float64
,complex128
(这只是一对float64
值)。即使是标准库中的大数字类型 big.Int
,big.Float
也无法从大数字常量中进行初始化-必须从字符串常量或其他表达式中反序列化它们。
基本机制很明显:这些常量仅在编译时存在,并且必须强制为某个可在运行时表示的值才能在运行时使用。它们是仅在代码中和编译期间存在的语言构造。您无法在运行时检索常量的原始值;它不存储在已编译程序本身的某个地址中。
因此问题仍然存在:为什么在实践中无法使用巨大的常量时,语言为什么要这么点呢?