这是一个简单的问题:这之间是否存在任何(性能)差异:
Person person = new Person()
{
Name = "Philippe",
Mail = "phil@phil.com",
};
Run Code Online (Sandbox Code Playgroud)
还有这个
Person person = new Person();
person.Name = "Philippe";
person.Mail = "phil@phil.com";
Run Code Online (Sandbox Code Playgroud)
您可以想象具有更多属性的更大对象.
该标准的 C++的书说,对于类类型成员的默认构造函数被隐式生成默认构造函数调用,但内建类型不被初始化.但是,在此测试程序中,当在堆中分配对象或使用临时对象时,我得到意外的结果:
#include<iostream>
struct Container
{
int n;
};
int main()
{
Container c;
std::cout << "[STACK] Num: " << c.n << std::endl;
Container *pc = new Container();
std::cout << "[HEAP] Num: " << pc->n << std::endl;
delete pc;
Container tc = Container();
std::cout << "[TEMP] Num: " << tc.n << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
[STACK] Num: -1079504552
[HEAP] Num: 0
[TEMP] Num: 0
Run Code Online (Sandbox Code Playgroud)
这是一些编译器特定的行为吗?我真的不打算依赖它,但我很想知道为什么会这样,特别是第三种情况.
c++ constructor initialization default-constructor object-initialization
考虑一下代码
auto p = new T( U(std::move(v)) );
Run Code Online (Sandbox Code Playgroud)
然后是初始化器U(std::move(v)).让我们假设T( U(std::move(v)) )不抛出.如果在底层内存分配之后评估初始化程序,则代码是强异常安全的.否则,事实并非如此.如果抛出内存分配,v就已经被移动了.因此,我对内存分配和初始化程序评估之间的相对顺序感兴趣.它是定义的,未指定的,还是什么?
c++ exception new-operator dynamic-memory-allocation object-initialization
以下两种情况有什么区别:
class Data
{
PersonDataContext persons = new PersonDataContext();
public Data() {}
}
Run Code Online (Sandbox Code Playgroud)
与
class Data
{
PersonDataContext persons;
public Data()
{
persons = new PersonDataContext();
}
}
Run Code Online (Sandbox Code Playgroud)
我在asp.net中有同样的问题:
public partial class Data : System.Web.UI.Page
{
PersonDataContext persons = new PersonDataContext();
protected void Page_Load(object sender, EventArgs e)
{
}
}
Run Code Online (Sandbox Code Playgroud)
与
public partial class Data : System.Web.UI.Page
{
PersonDataContext persons;
protected void Page_Load(object sender, EventArgs e)
{
persons = new PersonDataContext();
}
}
Run Code Online (Sandbox Code Playgroud) 在模块代码中初始化模块中的对象是不好的做法吗?
在Module.py:
class _Foo(object):
def __init__(self):
self.x = 'Foo'
Foo = _Foo()
Run Code Online (Sandbox Code Playgroud)
比在用户代码中,您可以:
>>> from Module import Foo
>>> print Foo.x
'Foo'
>>>
Run Code Online (Sandbox Code Playgroud)
...无需在用户代码中初始化 Foo 类。当然,只有在不需要参数来初始化对象时才有用。
有理由不这样做吗?
在我的 C# 代码中,我使用嵌套的事务范围。我有一个实用程序类,它以相同的方式创建 TransactionScope 对象。外部作用域和内部作用域的构造方式完全相同。
如果我像下面的第一个示例一样构造 TransactionScope 对象,则嵌套的事务范围可以很好地协同工作:
public static TransactionScope CreateTransactionScope()
{
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TransactionManager.MaximumTimeout;
return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我像这样构造 TransactionScope 对象,则会出现异常:
public static TransactionScope CreateTransactionScope()
{
var transactionOptions = new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
Timeout = TransactionManager.MaximumTimeout
};
return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
Run Code Online (Sandbox Code Playgroud)
错误内容为:“为 TransactionScope 指定的事务的 IsolationLevel 与为范围请求的值不同。参数名称:transactionOptions.IsolationLevel ”。
谁能向我解释为什么使用对象初始化会导致这种行为?
在Double 对象文档中,它只有两个构造函数,一个采用双精度值,另一个采用字符串值。但是,我刚刚发现,如果我们用其他 Number 类型对象初始化它,它也会起作用。例如,以下代码将起作用:
Integer i = Integer.valueOf(10);
Double d1 = new Double(i);
Long l = Long.valueOf(100);
Double d2 = new Double(l);
Run Code Online (Sandbox Code Playgroud)
所以我想知道这背后是什么?自动装箱/拆箱会在 Double/double、Long/long 和 Integer/int 之间进行转换,但我不明白为什么 Double 的构造函数会采用其他数据类型。
SomeObject *temp = [[SomeObject alloc] init]
self.theObject = temp;
[temp release];
Run Code Online (Sandbox Code Playgroud)
为什么总是这样做?为什么不
self.theObject = [[SomeObject alloc] init];
Run Code Online (Sandbox Code Playgroud) C#6引入了在没有setter的情况下初始化属性的功能,因此现在可以使用这种语法
public class MyClass
{
public int Answer { get; } = 42;
}
Run Code Online (Sandbox Code Playgroud)
甚至这个
public class MyClass
{
public int Answer { get; }
public MyClass()
{
Answer = 42;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道(或者更确切地说,强烈假设)这将被转换为readonly带有CIL中存取方法的生成字段,所以我理解这是怎么回事
public class MyClass
{
public int Answer { get; }
public MyClass CreateMyClassInstance()
{
return new MyClass()
{
Answer = 42
};
}
}
Run Code Online (Sandbox Code Playgroud)
不编译(因为赋值技术上发生在构造函数之外,这与支持readonly字段施加的限制冲突).
我的问题是为什么首先禁止这种行为?从语法和/或编译的角度来看,为什么属性赋值是属于对象初始值设定项的一部分的属性赋值,而不仅仅被视为在其后执行的额外内联逻辑,但仍然在对象的构造函数中?是设计,技术限制或向后兼容的结果,还是仅仅是一个不够重要的变化?
在Python中,我会这样做:
class foo:
def __init__(self):
self.x = self
Run Code Online (Sandbox Code Playgroud)
否则,现在该对象是其自身的参数.我怎样才能在普通的lisp中做到这一点?
(defclass mn ()
((pai :accessor mn-pai
:initarg :pai
:initform self)))
Run Code Online (Sandbox Code Playgroud) c# ×4
c++ ×2
oop ×2
properties ×2
.net ×1
asp.net ×1
c#-6.0 ×1
clos ×1
common-lisp ×1
constructor ×1
exception ×1
iphone ×1
java ×1
lisp ×1
new-operator ×1
objective-c ×1
performance ×1
python ×1
roslyn ×1
setter ×1