所以我希望能够在C#中模仿VB的“with”功能,并通过StackOverflow遇到了一个相当聪明的解决方案:
公共静态x与< x>(此x项,Func< x,x> f){ …
我认为你知道在施工过程中设置属性,这是类似的(更像是c#的惯用)?
class MySpecialClass { public string Property1 {get;set;} public int Length {get;set;} public float Width {get;set;} } var p = new MySpecialClass { Property1 = "PropertyValue", Length = 12, OtherThing = 1.234F };
这里的要点是对于一个方法 struct , 的含义 this 不是一个 值 (即你的价值 SomeStruct ),而是一个 参考 (一个 ref SomeStruct ,或有效地 in SomeStruct 在一个案例中 readonly struct )。
struct
this
SomeStruct
ref SomeStruct
in SomeStruct
readonly struct
您无法装入此表单的托管指针 - 这不是运行时支持的方案。托管指针只是在堆栈上。事实上,目前你甚至不能拥有 ref SomeStruct 自定义字段 ref struct 无法逃脱堆栈。
ref struct
编译器可以 作弊 通过 假装 这样做 - 即通过 提领 来自a的托管指针 ref SomeStruct 进入 SomeStruct 并创建一个捕获上下文 this 被解释为“ SomeStruct 我们之前解除引用“,但......然后编译器无法保证相同的行为和结果(实际上,我怀疑可以在 readonly struct 场景,但......不要引入那种微妙的区别可能更容易)。
相反,编译器建议您有效地执行上述步骤 手动 ;因为编译器不再处理 this ,它不再需要假装尊重通常的处理结果 this ,而只需要保证明确取消引用的行为 复制 的价值。这就是为什么它建议(至少在当前的编译器版本上):
考虑将'this'复制到匿名方法,lambda表达式或查询表达式之外的局部变量,并使用local。
因此,大多数lambdas,本地方法等都可以通过以下实用步骤来实现:
MyStruct copy = this; // dereference
然后在你的lambda / local方法/ etc中:而不是触摸 Something 又名 this.Something - 触摸 copy.Something 。它现在只是 copy 它被包含在捕获上下文中,并且 copy 不受约束 ref SomeStruct 规则(因为:它不是一个 ref SomeStruct - 它是一个 SomeStruct )。
Something
this.Something
copy.Something
copy
它 不 但是,如果你的意图是,那就意味着 的 变异 this 强> (并且可见 到位 ,而不是作为一个返回值),那么它将无法正常工作。你只会改变 的 复制 强> (即 copy )。这正是编译器必须要做的 无论如何 如果它已经撒谎,但至少现在复制步骤(取消引用)在您的代码中是明确且可见的。