分配 属性 时如何防止 get 访问器调用 set 访问器
How to prevent get accessor to call set accessor when assigning a property
适用于:.Net、C#、.Net 核心
问题描述:
这可能是 Edgecase,或者我做的事情完全错误。
我正在关注 Microsoft Documentation 以创建具有属性的 class。
Class 应该提供一个到活动目录的接口。
当我调用 get 访问器时,属性 可能尚未在我的程序中设置,因此 属性 应该从活动目录中拉出,设置为 class并返回。
为了节省资源,还没有设置的属性我只想拉。
问题是 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);
}
我考虑先检查是否为空,如果 属性 当前为空,则只在程序中设置它,不要将其推送到活动目录。但是,如何分配新属性呢?这些值不会被推送:
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
的私有字段并使用它重写您的 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);
}
}
}
个人建议设置前不要检查数值是否不同。使用您的代码的代码可以做到这一点,调用 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;
也更难意外导致 Whosebug。
适用于:.Net、C#、.Net 核心
问题描述:
这可能是 Edgecase,或者我做的事情完全错误。
我正在关注 Microsoft Documentation 以创建具有属性的 class。
Class 应该提供一个到活动目录的接口。
当我调用 get 访问器时,属性 可能尚未在我的程序中设置,因此 属性 应该从活动目录中拉出,设置为 class并返回。
为了节省资源,还没有设置的属性我只想拉。
问题是 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);
}
我考虑先检查是否为空,如果 属性 当前为空,则只在程序中设置它,不要将其推送到活动目录。但是,如何分配新属性呢?这些值不会被推送:
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
的私有字段并使用它重写您的 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);
}
}
}
个人建议设置前不要检查数值是否不同。使用您的代码的代码可以做到这一点,调用 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;
也更难意外导致 Whosebug。