当我重构以下行时:
Employee e = new Employee();
e.First = "Frank";
e.Last = "Rizzo";
Run Code Online (Sandbox Code Playgroud)
使用Resharper的"使用对象初始化器",我得到以下结果:
Employee e = new Employee
{
First = "Frank",
Last = "Rizzo"
};
Run Code Online (Sandbox Code Playgroud)
我真的很讨厌这种格式化,因为对象名称和变量越长,它就会失控.我怎样才能让Resharper做到以下几点?
Employee e = new Employee
{
First = "Frank",
Last = "Rizzo"
};
Run Code Online (Sandbox Code Playgroud) 当对象初始化器出现在C#中时,我太兴奋了.
MyClass a = new MyClass();
a.Field1 = Value1;
a.Field2 = Value2;
Run Code Online (Sandbox Code Playgroud)
可以改写得更短:
MyClass a = new MyClass { Field1 = Value1, Field2 = Value2 }
Run Code Online (Sandbox Code Playgroud)
对象初始化程序代码更加明显,但是当属性数量达到数十并且某些赋值处理可空值时,很难调试"空引用错误"的位置.Studio将整个对象初始值设定项显示为错误点.
现在我只使用对象初始化程序进行简单的赋值,以实现无错误的属性.
如何使用对象初始化程序进行复杂的分配,或者使用十几个分配是不好的做法?
先感谢您!
为什么不能在C#中的对象初始值设定项中分配事件和属性?这样做似乎很自然.
var myObject = new MyClass()
{
Property = value,
Event1 = actor,
// or
Event2 += actor
};
Run Code Online (Sandbox Code Playgroud)
还是有一些我不知道的技巧?
以下测试用例在尝试将Id分配给空的对象时抛出空引用异常,因为代码在对象初始值设定项之前缺少"new R".
为什么这不会被编译器捕获?为什么允许这样,用例会是一个有意义的构造?
[TestClass]
public class ThrowAway
{
public class H
{
public int Id { get; set; }
}
public class R
{
public H Header { get; set; }
}
[TestMethod]
public void ThrowsException()
{
var request = new R
{
Header =
{
Id = 1
},
};
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个关于在objective-c类中创建多个初始化器的简单问题.基本上我有一个代表我的数据库(用户)中的单行的类.我现在有这初始化基于用户类的初始化器用户ID(这也是数据库中的主键),当通过用户ID的类将它们连接到Web服务解析结果并返回初始化为相应的行对象在数据库中.
在这个数据库中有许多独特的字段(用户名和电子邮件地址),我也希望能够根据这些值初始化我的对象.但我不确定如何使用多个初始化程序,我读过的所有内容都表明我可以自由拥有多个初始化程序,只要每个程序都调用指定的初始化程序.如果有人可以帮我解决这个问题,那就太好了.
我的初始化代码如下:
- (id) initWithUserID:(NSInteger) candidate {
self = [super init];
if(self) {
// Load User Data Here
NSString *soapMessage = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<GetByUserID xmlns=\"http://tempuri.org/\">\n"
"<UserID>%d</UserID>\n"
"</GetByUserID>\n"
"</soap:Body>\n"
"</soap:Envelope>\n", candidate
];
NSLog(@"%@",soapMessage);
// Build Our Request
NSURL *url = [NSURL URLWithString:@"http://photoswapper.mick-walker.co.uk/UsersService.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"http://tempuri.org/GetByUserID" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage …Run Code Online (Sandbox Code Playgroud) 这段代码编译成功,但我认为它应该无法编译.此外,当你运行它时,你会得到一个NullReferenceException.丢失的代码是Bar属性初始化中的"新条形图" .
class Bar
{
public string Name { get; set; }
}
class Foo
{
public Bar Bar { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo
{
Bar = { Name = "Hello" }
};
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个已知的错误?
是否可以同时组合List初始化器和对象初始化器?给定以下类定义:
class MyList : List<int>
{
public string Text { get; set; }
}
// we can do this
var obj1 = new MyList() { Text="Hello" };
// we can also do that
var obj2 = new MyList() { 1, 2, 3 };
// but this one doesn't compile
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)
这是设计还是仅仅是c#编译器的错误或缺失功能?
从表面看,对象初始化器似乎对.net 4.0"代码契约"提出了问题,通常在对象构造函数完成时应该建立不变量.然而,据推测,对象初始化器需要在构造完成后设置属性.
我的问题是,"代码契约"的不变量是否能够处理对象初始化器,"好像"属性是在构造函数完成之前设置的?那确实非常好!!
.net design-by-contract .net-4.0 object-initializers code-contracts
请注意:这个问题和这个问题不一样.
我最近遇到了一些我以前没有遇到过的C#语法:
在F#中有没有办法做到这一点?
class Two
{
public string Test { get; set; }
}
class One
{
public One()
{
TwoProperty = new Two();
}
public Two TwoProperty { get; private set; }
}
var test = new One(){ TwoProperty = { Test = "Test String" }};
Run Code Online (Sandbox Code Playgroud)
(注意TwoProperty当setter是私有时初始化器中的初始化 - 它是在存储的对象上设置属性TwoProperty,但不在Two属性中存储新实例)
编辑:我最近在monotouch的构造函数中遇到了一些C#代码,如下所示:
nameLabel = new UILabel {
TextColor = UIColor.White,
Layer = {
ShadowRadius = 3,
ShadowColor = UIColor.Black.CGColor,
ShadowOffset …Run Code Online (Sandbox Code Playgroud) 在动态对象创建一个匿名类型的对象(即在对象初始化器内)时,属性是否可能以某种方式相互引用?我在下面的简化示例需要重用该Age属性,而不需要进行第二次大量调用GetAgeFromSomewhere().当然它不起作用.有关如何实现这一目标的任何建议?
var profile = new {
Age = GetAgeFromSomewhere(id),
IsLegal = (Age>18)
};
Run Code Online (Sandbox Code Playgroud)
对于动态对象匿名类型的对象初始化器,这样的事情是可能的还是不可能的?
c# ×7
.net ×3
.net-4.0 ×1
c#-3.0 ×1
c#-to-f# ×1
delegates ×1
events ×1
f# ×1
formatting ×1
objective-c ×1
properties ×1