给出以下代码;
public class CustomControl {
private object _dataItem;
public object DataItem {
get { return _dataItem; }
set { _dataItem = value; }
}
public void Update(ref string t) {
t = "test";
}
}
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
string prop = anyObject.anyProperty;
ctrl.Update(ref prop);
anyObject.anyProperty = prop;
}
}
Run Code Online (Sandbox Code Playgroud)
如何更改它以使DataItem属性本身成为引用,允许您先发制人地将其设置为指向变量,从而允许您在Update()没有任何参数的情况下调用.
因此,Consume类看起来类似于;
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
ctrl.Update();
// anyObject.anyProperty has been updated to "test"
}
}
Run Code Online (Sandbox Code Playgroud)
所以anyObject.anyProperty然后在内部处理分配CustomControl
你需要存储设置字符串的行为,所以存储一个Action<string>:
public class CustomControl {
public Action<string> SetData { get; set; }
public void Update() {
// TODO nullity check
SetData("test");
}
}
Run Code Online (Sandbox Code Playgroud)
然后Consume看起来像:
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
// store {the act of setting this property of this object to a string}
ctrl.SetData = s => anyObject.anyProperty = s;
ctrl.Update();
}
}
Run Code Online (Sandbox Code Playgroud)
的Update通话将设置anyObject.anyProperty到test.请注意,您特意存储了 在赋值中设置此引用的特定anyObject属性的操作SetData.
要扩展lambda:我们想要创建一个类型的值Action<string>,即一个接受a string并且不返回结果的东西.这样的事情将成为可执行代码.在C#3之前,要创建一个可执行代码的"值",我们必须做以下事情:
ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };
Run Code Online (Sandbox Code Playgroud)
使用这种语法更明显的是我们正在创建一个方法 - 它有一个{ }分隔的主体,它有语句,很明显有一个主体使用的字符串参数.
在C#3中通过lambda表达式实现的一件事就是能够将其压缩; 松散地,整个
// not compilable code
delegate(parameters) { body; }
Run Code Online (Sandbox Code Playgroud)
可以替换为
// not compilable code
(parameters) => body;
Run Code Online (Sandbox Code Playgroud)
并且在只有一个参数的情况下
// not compilable code
parameter => body;
Run Code Online (Sandbox Code Playgroud)
这就是我们在这里:分配给表达式ctrl.SetData是一块行为接受字符串(s),并设置anyObject.anyProperty该字符串.真正的力量在于C#编译器能够计算出类型的方式,知道我们正在创建一个类型Action<string>.