c属性setter主体,而不声明类级属性变量

本文关键字:属性 声明 变量 setter 主体 | 更新日期: 2023-09-27 18:19:36

我需要声明一个类级变量来保存属性吗?或者我可以只引用getter/setter中的self.{propertyname}吗?

换句话说,我可以这样做吗?(我在任何地方都没有定义mongoFormId):

public string mongoFormId 
{
    get
    {
        return this.mongoFormId;
    }
    set
    {
        this.mongoFormId = value;
        revalidateTransformation();
    }
}

c属性setter主体,而不声明类级属性变量

您可以使用自动访问器实现自己的访问器。如果您使用自动访问器,C#编译器将为您生成一个支持字段,但如果您实现自己的支持字段,则必须手动提供一个支持域(或以其他方式处理值)。

private string _mongoFormId;
public string mongoFormId 
{
    get { return this._mongoFormId; }
    set 
    {
        this._mongoFormId = value;
        revalidateTransformation();
    }
}

更新:自从提出这个问题以来,C#6.0已经发布。然而,即使有了新的语法选项,仍然无法在不需要显式声明支持字段的情况下提供自定义的setter主体。

如果要使用自定义getter和setter,则需要设置一个字段变量并将值存储在那里。

使用现在的代码,您将遇到堆栈溢出异常。当您为mongoFormId分配一些内容时,您将执行行this.MongoFormId = value;。这是对mongoFormId的赋值,导致执行行this.MongoFormId = value;,依此类推。它永远不会停止。

正确的方式是一个字段:

    private string _mongoFormId;
    public string mongoFormId {
        get { return this._mongoFormId; }
        set {
            this._mongoFormId = value;
            revalidateTransformation();
        }
    }

您应该有一个后备变量。仔细看一下:

get { return this.mongoFormId; }

将调用mongoFormId上的getter,它将一次又一次地调用该代码!定义一个后备变量将避免无限递归调用。

查看MSDN属性概述

虽然属性定义通常包括私有数据成员,这不是必需的。get访问器可以返回一个没有访问私有数据成员。一个例子是方法返回系统时间。属性启用数据隐藏访问器方法隐藏属性的实现。

这两种方法都可以。

如果你想有一个类级别的成员变量,那么可以这样做-

public class sampleClass
{
     private string _mongoFormId;
public string mongoFormId {
            get { return _mongoFormId; }
            set {
                _mongoFormId = value;
                revalidateTransformation();
            }
        }
}

或者在类中简单地执行此操作,如果不需要重新验证Transformation()执行,则调用

public class sampleClass
{
public string mongoFormId {get; set;}
}

这将不起作用,因为您得到了对属性的递归调用。如果我没有记错的话,结果将是StackOverflowException。必须使用变量。

    private string mongoFormId;
    public string MongoFormId 
    {
        get
        {
            return this.mongoFormId;
        }
        set
        {
            this.mongoFormId = value;
            revalidateTransformation();
        }
    }

如果不必执行revalidateTransformation,则可以使用auto属性。这将在场景后面为您创建背景文件。

public string MongoFormId { get; set; }

使用您编写的代码,您将在get和set上创建一个递归的无休止循环。this关键字指的是当前类,而不是您所在的属性。

所以,是的,你需要声明一个私有字段。为了避免混淆,请按照MSDN命名指南创建属性(属性使用Pascal大小写,私有字段使用camel大小写)。请对您的方法执行同样的操作,如果您遵循C#约定而不是java约定,则应该是RevalidateTransformation而不是revalidateTransformation

private string mongoFormId;
public string MongoFormId 
{
    get 
    { 
        return mongoFormId; 
    }
    set 
    {
        mongoFormId = value;
        RevalidateTransformation();
    }
}
public string mongoFormId {
    get {
        return this.mongoFormId;
    }
    set {
        this.mongoFormId = value;
        revalidateTransformation();
    }
}

这样就可以在所有路径上递归函数我看到的唯一方法是使用私有数据成员。正如其他男孩告诉的那样。