从setter中返回值

3

我有一个不可变的结构体,希望保持它的不可变性,但也想允许类似 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) 起作用?


3
这是错误的。为什么你想从一个setter方法中返回一个值? - Leo
1
p1.v中的v是什么?你是指N吗?是的,我同意@Leo的观点,你不能在属性设置器中使用return语句。这样做行不通。 - Bairose
@user60561:你能澄清一下你想做什么吗?那个语法应该达到什么效果? - Jeroen Vannevel
@Jeroen Vannevel public Number setN(int newN){ return new Number(int newN);} 如果有多个数字,这段代码可以显著缩短。 - flaviut
1
@它不够简洁(可能很短)。方括号通常与(数组)索引器相关联。滥用(数组)索引器语法来节省源代码中的几个字符将导致误解和混淆 - 这是不好的做法,可以这么说。严格来说,方括号索引器并不仅限于为数组和集合实现(尽管这是大多数人知道的),而且还可以为您实现的任何数据集实现基于索引的访问。这是你想要实现的吗? - user2819245
显示剩余14条评论
4个回答

5
不,没有这样的语法会起作用。设置器是设置器,不是获取东西的方法。

2
首先,您想做一些没有人能够阅读的事情。如果您的结构是不可变的,那么当执行p1.v = 3时会发生什么?显然,p1不应该改变,没有人期望setter返回值...唯一合理的行为是看到异常"This object is immutable",但是缺少setter更好地指示了属性是只读的....

可能您正在尝试实现类似于流畅接口的东西,这更为常见:

 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); }
 }

0

你应该只从 getters 中返回值。


2
可以吗?不行。应该吗?很可能。 - Jeroen Vannevel
@JeroenVannevel,在C#中的属性访问器上,setters是不能返回值的。(不要与SetXXX/GetXXX方法混淆,尽管在这里称呼一个方法为setter只是一种惯例...) - user2819245
肯定的是,这种措辞让人觉得他指的是常见的setter方法。 - Jeroen Vannevel
当我说“你只能从getter返回值”时,我完全错了吗? - Ojonugwa Jude Ochalifu
1
@OjonugwaOchalifu,不,你并没有完全错,只是有歧义。在C#中引入属性get/set访问器之前,“setter”和“getter”这些术语仅用于普通方法,例如GetWidth/SetWidth或类似方法(在其他语言中仍在使用)。由于它们只是方法,因此可以实现具有返回类型的setter(setter方法!)。对于属性setter(set访问器!),这在语法上是不可能的-如果您尝试返回值,编译器会给出错误消息。 - user2819245

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中也进行了检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接