MSDN说你应该在需要轻量级对象时使用结构.当结构比类更可取时,还有其他任何情况吗?
有些人可能忘记了:
我理解结构和类之间的技术差异,我只是对使用结构时没有很好的感觉.
在.NET中,值类型(C#struct)不能包含没有参数的构造函数.根据这篇文章,这是CLI规范要求的.会发生什么,对于每个值类型,都会创建一个默认构造函数(由编译器?),它将所有成员初始化为零(或null).
为什么不允许定义这样的默认构造函数?
一个微不足道的用途是有理数:
public struct Rational {
private long numerator;
private long denominator;
public Rational(long num, long denom)
{ /* Todo: Find GCD etc. */ }
public Rational(long num)
{
numerator = num;
denominator = 1;
}
public Rational() // This is not allowed
{
numerator = 0;
denominator = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
使用当前版本的C#,默认的Rational 0/0并不是那么酷.
PS:默认参数是否有助于解决C#4.0或者是否会调用CLR定义的默认构造函数?
Jon Skeet回答道:
要使用您的示例,当有人执行时您希望发生什么:
Run Code Online (Sandbox Code Playgroud)Rational[] fractions = new Rational[1000];它应该通过你的构造函数1000次?
当然应该,这就是我首先编写默认构造函数的原因.当没有定义显式默认构造函数时,CLR应该使用默认的归零构造函数; 这样你只需支付你使用的费用.然后,如果我想要一个1000个非默认Rational的容器(并希望优化1000个结构),我将使用一个 …
在C#设置中,只要变量的大小最大native int(即32位运行时环境中的4个字节和64位上的8个字节),变量的值就是原子级.在一个64位的环境,它包括所有的引用类型和最内置值类型(byte,short,int,long,等等).
设置更大的值不是原子的,并且可能导致仅更新部分内存的撕裂.
DateTime是一个结构,它只包含一个ulong包含其所有数据(Ticks和DateTimeKind)的字段,并且ulong在64位环境中本身是原子的.
这是否意味着它DateTime也是原子的?或者以下代码是否会在某些时候导致撕裂?
static DateTime _value;
static void Main()
{
for (int i = 0; i < 10; i++)
{
new Thread(_ =>
{
var random = new Random();
while (true)
{
_value = new DateTime((long)random.Next() << 30 | (long)random.Next());
}
}).Start();
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud) 我想知道这里是否有人知道c#中定点数学的任何好资源?我见过这样的事情(http://2ddev.72dpiarmy.com/viewtopic.php?id=156)和这个(定点数学的最佳方法是什么?),以及关于是否十进制的一些讨论实际上是固定点或实际浮点(更新:响应者已经确认它肯定是浮点数),但是我还没有看到一个可靠的C#库来计算余弦和正弦.
我的需求很简单 - 我需要基本的操作符,加上余弦,正弦,arctan2,PI ...我认为这就是它.也许sqrt.我正在编写一个2D RTS游戏,我已经在很大程度上工作了,但是使用浮点数学(双精度)时的单位运动在多台机器上随着时间的推移(10-30分钟)有很小的不准确性,从而导致了desyncs.目前这只是在32位操作系统和64位操作系统之间,所有32位机器似乎保持同步没有问题,这使我认为这是一个浮点问题.
我从一开始就意识到这是一个可能的问题,所以尽可能地限制了我对非整数位置数学的使用,但是为了在不同的速度下平滑对角线移动,我正在以弧度计算点之间的角度,然后用sin和cos得到运动的x和y分量.这是主要问题.我还对线段交叉点,线圆交叉点,圆矩交点等进行了一些计算,这些计算也可能需要从浮点移动到定点以避免跨机器问题.
如果在Java或VB或其他类似语言中有开源的话,我可能会将代码转换为我的用途.我的主要优先考虑的是准确性,尽管我希望尽可能减少速度损失而不是现在的性能.这整个定点数学对我来说是非常新的,我很惊讶谷歌上的实用信息很少 - 大多数东西似乎是理论或密集的C++头文件.
你可以做的任何事情都指向我正确的方向非常感谢; 如果我可以使这个工作,我计划开源我放在一起的数学函数,以便有其他C#程序员的资源.
更新:我绝对可以使余弦/正弦查找表适用于我的目的,但我认为这不适用于arctan2,因为我需要生成一个包含大约64,000x64,000个条目(yikes)的表.如果您知道有关计算arctan2等事物的有效方法的任何程序性解释,那将是非常棒的.我的数学背景还可以,但是高级公式和传统的数学符号对我来说很难翻译成代码.
请帮助我们解决"几乎"的争议一切都是一个对象(Stack Overflow问题的答案作为一个新手,在学习C#之前有什么我应该注意的吗?).我认为就是这种情况,因为Visual Studio中的所有内容至少都显示为结构体.请张贴参考文献,以免它变成"现代傻瓜"(This American Life).
请注意,这个问题涉及C#,不一定是.NET,以及它如何处理引擎盖下的数据(显然它都是1和0).
以下是"一切都是对象"的评论:
对象的定义:"对象"作为类System.Object的继承者与"对象"作为类型与"对象"作为引用类型的实例."
我的理解是现在允许结构中的无参数构造函数.
但是下面的代码在VS 2015社区中给出了编译错误
public struct Person
{
public string Name { get; }
public int Age { get; }
public Person(string name, int age) { Name = name; Age = age; }
public Person() : this("Jane Doe", 37) { }
}
Run Code Online (Sandbox Code Playgroud)
错误:"结构不能包含显式无参数构造函数"
谁知道为什么?
在定义具有引用类型成员的结构(而不是将其定义为类)时是否有任何意义?例如,要定义此结构:
public struct SomeStruct
{
string name;
Int32 place;
}
Run Code Online (Sandbox Code Playgroud)
我问,因为我知道结构是一个值类型,并在其中定义一些引用类型没有任何意义.
我对吗?有人可以解释一下吗?
public struct Test
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}
Test myTest = new Test();
bool valid = myTest.IsValid;
Run Code Online (Sandbox Code Playgroud)
上面给出了valid==true因为没有调用默认arg的构造函数,并且使用标准默认值val = 0.0创建了对象.
如果结构是一个类,那么行为就是valid==false我所期望的.
我发现这种行为上的差异,特别是结构案例中的行为令人惊讶和不直观 - 发生了什么?stuct构造的默认arg服务是什么? 如果它无用为什么要让这个编译?
更新:澄清这里的重点不在于行为是什么 - 而是为什么在没有警告的情况下进行编译并且行为不直观.即如果没有应用默认的arg,因为在新的Test()情况下没有调用构造函数,那么为什么要让它编译?
可能重复:
哪个最适合数据存储结构/类?
考虑一个示例,其中我有一个Employee对象,其中包含年龄,姓名,性别,职称,薪水等属性.我现在有一个列表,我想填充一堆Employees(每个Employee实例是唯一的).
就速度和内存占用而言,将员工创建为Struct还是Class更为可取?
关于上述场景中Struct和Class的任何其他警告都是受欢迎的
Int的大小为4个字节,如果我在程序中创建一个新的Int将使其内存消耗增加4个字节.对?
但如果我有这门课
public class Dummy{
private int;
}
Run Code Online (Sandbox Code Playgroud)
我的新课程将使用多少内存?如果它是一个结构,内存消耗会更低吗?我认为引用本身也会消耗一些内存.
c# ×8
.net ×6
struct ×4
c#-6.0 ×1
class ×1
clr ×1
concurrency ×1
datetime ×1
fixed-point ×1
math ×1
memory ×1
object ×1
oop ×1
tearing ×1
value-type ×1