我有一个不可变的结构,并希望保持它不可变,但也允许像var p2 = p1.v = 3
这样的原理图。我认为以下可能有用,但似乎不是:
public struct Number {
readonly int n;
public int N {
get{ return n; }
set{ return new Number(value); }
}
public Number(int newN) {
n = newN;
}
}
有没有办法让var p2 = p1.v = 3
或var p2 = (p1.v = 3)
工作?
答案 0 :(得分:5)
不,没有这样的语法可行。 Setter是, setters ,而不是获取的东西。
答案 1 :(得分:2)
首先,你想要做一些没有人能够阅读的事情。如果结构是不可变的,那么p1.v = 3
的结果应该是什么?显然p1
不应该改变,没有人期望setter返回值...唯一合理的行为是看到异常“这个对象是不可变的”,但是缺少setter会更好地指示属性只读....
可能你试图实现更常见的fluent interface之类的东西:
var newValue = oldValue.WithOneProperty(5).WithOtherProperty(3);
class Number
{
int oneProperty;
int otherProperty;
Number WithOneProperty(int v) { return new Number(v, this.otherProperty); }
Number WithOtherProperty(int v) { return new Number(this.oneProperty, v); }
}
答案 2 :(得分:0)
您应该只从getter返回值。
答案 3 :(得分:0)
我认为使用一次性代币或密钥可以有效地使用它。我在这里使用了一些代码来生成这个:
public class MyController : Controller
{
private static string m_oneTimeKey = "this key hasn't been initialised yet";
private string oneTimeKeyGet()
{
// Return the last key
string returnValue = MyController.m_oneTimeKey;
// Generate a new random key so the one we return can't be reused
var m_oneTimeKey = GetRandomString();
return returnValue;
}
private string oneTimeKeySet()
{
// Generate a new random key
var newValue = GetRandomString();
m_oneTimeKey = newValue;
return newValue;
}
private string GetRandomString()
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var returnValue = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
return returnValue;
}
然后我用它:
var myURL = "/Index?id=" + ID + "&key=" + oneTimeKeySet();
在ActionResult中,我可以验证这是否是一次性调用:
public ActionResult Index(Guid id, string key)
{
if (key == oneTimeKeyGet() {
....
}
}
}
我实际上更进了一步,我还有一个在函数之间传递的静态键,也在ActionResult中的if中检查。