相关疑难解决方法(0)

为什么可变结构"邪恶"?

在这里讨论了SO之后,我已经多次读过可变结构是"邪恶"的评论(就像这个问题的答案一样).

C#中可变性和结构的实际问题是什么?

c# struct mutable immutability

470
推荐指数
15
解决办法
7万
查看次数

为什么const-correctness特定于C++?

免责声明:我知道有两个关于const-correctness有用的问题,但是,没有人讨论过如何在C++中使用const-correctness 而不是其他编程语言.此外,我对这些问题的答案不满意.

我现在使用了一些编程语言,在C++中让我烦恼的一件事就是const-correctness的概念.在Java,C#,Python,Ruby,Visual Basic等中没有这样的概念,这似乎对C++非常具体.

在你推荐我使用C++ FAQ Lite之前,我已经阅读了它,但这并不能说服我.完全有效,可靠的程序一直用Python编写,没有const关键字或等价物.在Java和C#中,对象可以声明为final(或const),但是没有const成员函数或const函数参数.如果函数不需要修改对象,则它可以采用仅提供对象的读访问权的接口.该技术同样可以在C++中使用.在我工作的两个真实的C++系统上,几乎没有使用const,一切都运行正常.因此,对于让const污染代码库的有用性,我还远没有卖掉.

我想知道在C++中它是什么让const成为必要,而不是其他编程语言.

到目前为止,我只看到了必须使用const的一种情况:

#include <iostream>

struct Vector2 {
    int X;
    int Y;
};

void display(/* const */ Vector2& vect) {
    std::cout << vect.X << " " << vect.Y << std::endl;
}

int main() {
    display(Vector2());
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio接受使用const注释掉的编译,但是使用警告C4239时,使用非标准扩展.所以,如果你想要传递临时代码,避免副本和保持标准兼容的语法简洁,你必须通过const引用,不管它.不过,这更像是一个怪癖,而不是一个根本原因.

否则,实际上不存在必须使用const的情况,除非与使用const的其他代码连接.在我看来,康斯特似乎不是一个自以为是的瘟疫,它蔓延到它接触到的一切:

const在C++中工作的原因是因为你可以把它丢弃.如果你不能把它扔掉,那么你的世界就会糟透了.如果声明一个采用const Bla的方法,则可以将它传递给非const Bla.但如果是相反的方式你不能.如果声明一个采用非const Bla的方法,则不能将它传递给const Bla.所以现在你被卡住了.所以你逐渐需要一个不是const的所有东西的const版本,你最终得到了一个阴影世界.在C++中,你可以使用它,因为与C++中的任何东西一样,无论你是否想要这个检查,它都是纯粹可选的.如果你不喜欢它,你可以打破常量.

Anders Hejlsberg(C#架构师),CLR设计选择

c++ const const-correctness

40
推荐指数
7
解决办法
7237
查看次数

我应该使用struct还是class?

我处在一个经典的设计困境中.我正在编写一个C#数据结构来包含一个值和测量单位元组(例如7.0毫米),我想知道我是否应该使用引用类型或值类型.

结构的好处应该是减少堆操作,从而使我在表达式中获得更好的性能并减少对垃圾收集器的压力.对于像这样的简单类型,这通常是我的选择,但在这个具体案例中存在缺点.

元组是相当通用的分析结果框架的一部分,其中结果在WPF应用程序中以不同方式呈现,具体取决于结果值的类型.WPF及其所有数据模板,值转换和模板选择器都可以很好地处理这种弱类型.这意味着如果我的元组表示为结构,则该值将经历大量装箱/拆箱.实际上,在表达式中使用元组对于在拳击场景中的使用来说将是次要的.为了避免所有的拳击,我考虑将我的类型声明为一个类.关于结构的另一个担心是在WPF中可能存在双向绑定的缺陷,因为在代码中的某处而不是引用副本更容易得到元组的副本.

我也有一些方便的运算符重载.我可以使用重载的比较运算符比较毫米和毫米毫米没有问题.但是我不喜欢重载==和!=的想法,如果我的元组是一个类,因为约定是==和!=是引用类型的ReferenceEquals(与System.String不同,这是另一个经典的讨论).如果==和!=重载,有人会写if(myValue == null)并在myValue有一天结果为null时得到一个讨厌的运行时异常.

另一个方面是在C#中没有明确的方法(与例如C++不同)在代码使用中区分引用和值类型,但语义是非常不同的.我担心我的元组的用户(如果声明了struct)假定该类型是一个类,因为大多数自定义数据结构都是并且假设是引用语义.这是另一个争论,为什么人们应该更喜欢类,因为那是用户所期望的,而且没有"." /" - >"告诉他们分开.一般来说,我几乎总是会使用一个类,除非我的探查器告诉我使用一个结构,只是因为类语义最有可能是其他程序员所期望的,而C#只有模糊的提示,无论它是一个还是另一个.

所以我的问题是:

在决定是否应该重视或参考时,我还应该考虑哪些其他因素?

可以== /!=在类中重载在任何情况下都是合理的吗?

程序员假设的东西.大多数人可能会认为称为"点"的东西是值类型.如果您阅读一些带有"UnitValue"的代码,您会假设什么?

根据我的使用说明你会选择什么?

c# boxing class-design

9
推荐指数
1
解决办法
1357
查看次数

C#会从聚合结构/类中受益吗?

前言

tl; wr:这是一个讨论.

我知道这个"问题"更多的是讨论,因此我将其标记为社区维基.但是,根据" 如何询问"页面,它可能属于此处,因为它具体与编程相关,经过一个小时的研究后无法在网络上讨论,具体而言,与大多数C#程序员和主题相关.而且,这个问题本身就是为了获得答案,不管我的偏见,我都会保持开放的态度:C#真的会从总体结构中受益吗?尽管有这一前言,但我知道这是关闭的,但如果有权限和意图关闭的用户将我重定向到Web上的适当讨论点,我将不胜感激.


介绍


缺乏结构可变性

结构是C#中的灵活但有争议的类型.它们提供堆栈分配的值类型组织范例,但不提供其他值类型的不变性.

有人说结构应该代表值,而值不会改变(例如int i = 5;,5是不可变的),而有些人认为它们是带有子字段的OOP布局.

上结构不变性(辩论1,2,3),为此,当前的解决方案似乎具有程序员执行不变性,也没有解决.

例如,当结构作为引用(本页底部)访问并限制赋值时,C#编译器将检测可能的数据丢失.此外,由于结构构造函数,属性和函数能够执行任何操作,在返回控件之前使用限制(对于构造函数)分配所有字段,结构不能声明为常量,如果它们仅限于数据表示.


不可变的结构子集,聚合

聚合类(维基百科)是严格的数据结构,功能有限,注定会因缺乏灵活性而在对应方面提供语法糖.在C++中,它们"没有用户声明的构造函数,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数".尽管核心概念保持不变,但C#中此类类别的理论细节仍可供讨论.

由于聚合结构是严格的带有标记访问器的数据持有者,因此它们的不变性(在可能的C#环境中)将被保险.除非?指定了null运算符(),否则聚合也无法为空,无其他纯值类型.出于这个原因,许多非法的结构操作将成为可能,以及一些语法糖.


用途


  1. 聚合可以声明为const,因为它们的构造函数将被强制除了分配字段之外什么都不做.
  2. 聚合可以用作方法参数的默认值.
  3. 聚合可以是隐式顺序,促进与本机的交互
  4. 聚合将是不可变的,不会导致参考访问的数据丢失.编译器检测到这些子字段修改可能会导致完整的隐式重新分配.libraries.

假设语法


从C++语法中我们可以想象出以下几点:(记住,这是一个社区维基,欢迎并鼓励改进)

aggregate Size
{
    int Width;
    int Height;
}

aggregate Vector
{
    // Default values for constructor.
    double X = 0, Y = 0, Z = 0;
}

aggregate Color
{
    byte R, G, B, …
Run Code Online (Sandbox Code Playgroud)

c# struct aggregate class

8
推荐指数
1
解决办法
2387
查看次数

结构 - 它的用途是什么?

我对struct类型有所了解.但我无法理解:它是为了什么?我什么时候用它?类,简单的值类型和枚举 - 这就是我所需要的.

有什么建议?

UPD:请!不要告诉我结构在堆栈中(我知道这个:).什么结构用于?

c# struct

7
推荐指数
3
解决办法
1432
查看次数

是否像List <String,Int32,Int32>(多维通用列表)

我需要类似的东西List<String, Int32, Int32>.List一次只支持一种类型,而Dictionary一次只支持两种类型.是否有一种干净的方式来做上面的事情(一个多维通用列表/集合)?

c# collections list generic-list

7
推荐指数
2
解决办法
6590
查看次数

单个类类型的C#数组或列表

我有一个包含一些基本类型的类.(3x float,2x int).

现在我需要一个可以容纳这个类的数百万个实例的集合.我不需要派生类型.所有元素都完全来自这个单独的类.更多元素的数量是固定的.在极少数情况下,我计划复制整个列表/数组并修改副本.最初的列表/数组应该是不可变的,因此我不需要与其他线程同步.

现在的问题是:

  • 我是从数组而不是列表中受益吗?
  • 我是否使用数组保存内存?
  • 速度怎么样?

我读到C#中的List也在内部实现为Array.

如果它是C++,我知道数组将保存完整的对象.但我不确定C#如何处理这个问题.C#数组是仅保存对类实例的引用还是保存完整的数据结构?

c# arrays list

6
推荐指数
1
解决办法
1736
查看次数

为什么struct可以改变自己的领域?

考虑Foo结构如下:

struct Foo
{
  public float X;
  public float Y;

  public Foo(float x, float y)
  {
    this.X = x;
    this.Y = y;
  }

  public void Change(float x)
  {
    this.X = x;
  }
}
Run Code Online (Sandbox Code Playgroud)

我理解修改构造函数中的字段,这对我和我理解结构作为值,类似数字的不可变类型是完全合乎逻辑的.

然而,因为可以T"做:

Foo bar = new Foo(1, 2);
bar.X = 5;
Run Code Online (Sandbox Code Playgroud)

为什么可以使用:

Foo bar = new Foo(1, 2);
bar.Change(5);
Run Code Online (Sandbox Code Playgroud)

编辑:如果结构是可变的,那么为什么它们不能在列表中修改或从属性返回?

无法修改表达式,因为它不是变量

c# struct

5
推荐指数
2
解决办法
5657
查看次数

结构没有身份时意味着什么?

我在这里阅读了几个关于结构的线程(一个关于可变结构)并且我一直在阅读结构应该如何没有标识.

结构中缺少身份究竟是什么?我猜它会像一个数字,例如5,没有上下文(5什么?).客户是期待服务的人,因此有一个身份.我在想什么?

我知道技术差异以及结构如何是线程安全的(只要它们不能被变异,但我仍然可以编写变异状态的方法),每次将它们传递给方法时都会有新副本等等......

c#

2
推荐指数
1
解决办法
148
查看次数

C# - 2个结构问题

我知道结构是值类型,但后来我不明白为什么这样有效:
编辑:我的意思是,为什么this.Size.Height不起作用呢?

struct A
{
    int height;

    public int Height
    { 
        get
        {
            return height;
        }

        set
        {
            height = value;
        }
    }
}

//... class Main
{
    A a = A();
    a.Height = 5;  //works. Why? I thought it should say "cannot modify as it is not variable". I think the properties should return copy of this struct...?
}
Run Code Online (Sandbox Code Playgroud)

第二个问题 - 我已经阅读过我不需要使用带有结构的"新"但如果没有它我就无法使用它.

c# struct properties

1
推荐指数
1
解决办法
233
查看次数

为什么当一个相同类中的字段没有时,结构中的字段会丢失其值?

我有一个带有一个字段的结构,它失去了它的价值.我可以将字段声明为静态并解决问题.我也可以将struct更改为class(不改变任何其他内容),这也解决了问题.我只是想知道为什么会这样?

.net c# struct field

1
推荐指数
1
解决办法
818
查看次数

在C中的数组中迭代

嘿,我有这种类型的东西

eph_t *a;
Run Code Online (Sandbox Code Playgroud)

你可以看到类型是eph_t.它是C中的数组,但我不知道数组的大小,也不知道数组的最终元素是什么.有没有办法,我可以浏览整个数组,因为我想将数组中每个元素的值赋给某些东西.

我可以考虑哪些选择?如果您无法理解问题中的某些内容,只需发表评论,以便我可以通知您.

c arrays

1
推荐指数
2
解决办法
225
查看次数

为什么日期时间变为16年前的1月1日并未正确显示年份?

我希望从今天开始将日期设置为16年前的1月1日.我用过代码

DateTime dtm = new DateTime(DateTime.Today.Year, 1, 1);
dtm.AddYears(-16);
dtpDOB.Value = dtm;// assign value to date time picker
Run Code Online (Sandbox Code Playgroud)

但它显示日期值为2014年1月1日,为什么这不会将年份部分设置为16年?

谢谢

c# datetime

1
推荐指数
1
解决办法
81
查看次数