【问题标题】:How to prevent get accessor to call set accessor when assigning a property分配属性时如何防止获取访问器调用设置访问器
【发布时间】:2020-11-17 13:49:44
【问题描述】:

适用于:.Net、C#、.Net 核心

问题描述:

这可能是一个 Edgecase 或者我做错了什么。
我正在关注Microsoft Documentation,以便创建一个具有属性的类。 该类应提供到活动目录的接口。

当我调用 get 访问器时,该属性可能尚未在我的程序中设置,因此应从活动目录中提取该属性,设置为类并返回。

为了节省资源,我只想拉取尚未设置的属性。 问题是 Get Accessor 调用 Set Accessor 以便在我的程序中设置属性。
然后 Set 访问器本身尝试将“新”值推回活动目录,即使我想从活动目录进行只读操作。

可重现的代码:

这是此类属性的一个示例:

/// <summary>
/// sAMAccountName - the logon name. eg. "musterma1"
/// </summary>
public string LogonName
{
    get
    {
        // if the value is not set,pull it from active directory
        LogonName ??= GetProperty("sAMAccountName");// if null, pull value;
        return LogonName;
    }
    set
    {
        if (value != LogonName)
        {
            // if the value has changed, push it to active directory
            LogonName = value;
            SetProperty("sAMAccountName", LogonName);
        }
    }
}
// further properties here

/// <summary>
/// this function calls the corresponsing active directory function in order 
/// to populate a poperty of the given user
/// </summary>
/// <param name="property">which property to populate</param>
/// <param name="value">what value should the property have?</param>
private void SetProperty(string property, string value)
{
    ObjectProperties.SetProperty(property, value, this.DistinguishedName);
}
/// <summary>
/// this function calls the corresponsing active directory function in order 
/// to receive the current users property
/// </summary>
/// <param name="property">which property to poulate</param>
private string GetProperty(string property)
{
    return ObjectProperties.AttributeValuesSingleString("property", this.DistinguishedName);
}

我考虑过先检查是否为null,如果该属性当前为null,则只在程序中设置它,不要将其推送到活动目录。但是,那么分配新属性呢?这些值不会被推送:

set
{
    if (LogonName == null) LogonName = value;
    else if (value != LogonName)
    {
        // if the value has changed, push it to active directory
        LogonName = value;
        SetProperty("sAMAccountName", LogonName);
    }
}

问题:

你知道如何在我的程序中调用 get 访问器并设置属性而不调用 set 访问器并立即将属性推回活动目录吗?

【问题讨论】:

  • 给你的财产LogonName一个支持值logonName

标签: c# .net .net-core properties get


【解决方案1】:

您应该创建名为 _logonName 的私有字段并使用它重写您的 Get\Set。例如:

private string _logonName;

public string LogonName
{
    get
    {
        // if the value is not set,pull it from active directory
        _logonName ??= GetProperty("sAMAccountName");// if null, pull value;
        return _logonName;
    }
    set
    {
        if (value != _logonName)
        {
            // if the value has changed, push it to active directory
            _logonName = value;
            SetProperty("sAMAccountName", _logonName);
        }
    }
}

【讨论】:

  • -.- 非常感谢。有时,我们在德国所说的所有树木都看不到森林
  • @julianbechtold Bitte schön。维尔格吕克
【解决方案2】:

我个人建议在设置之前不要检查值是否不同。使用您的代码的代码可以做到这一点,调用 Set 访问器总是会设置一些东西是有道理的。

我会改写如下

public string LogonName
{
    get
    {
        // if the value is not set,pull it from active directory
        LogonName ??= GetProperty("sAMAccountName");// if null, pull value;
        return LogonName;
    }
    set
    {
            // if the value has changed, push it to active directory
            LogonName = value;
            SetProperty("sAMAccountName", LogonName);
    }
}

然后,如果您关心性能,则只需在设置之前使用您的代码进行测试即可。 即

if(class.logonName != newName) 
     class.logonName = newName;

还使得意外导致堆栈溢出变得更加困难。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多