如何解决循环属性 c#
static TestInitialization()
{
client = new HttpClient();
client.BaseAddress = new Uri( URL_BASE_ADRESS );
client.DefaultRequestHeaders.Add( "auth-key",Auth_Token );
}
private const String path = @"f:\specialproject\authdata.txt";
internal static readonly String Login = File.ReadLines( path ).First(); //login in this file must be the first line
internal static readonly String Password = File.ReadLines( path ).Last();//password - as second line
internal static String Auth_Token
{
get
{
if( Auth_Token != null )
return Auth_Token;
else
return LoginAndGetToken();
}
set
{
Auth_Token = LoginAndGetToken();
}
}
internal static String LoginAndGetToken()
{
HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post,$"{URL_BASE_ADRESS}/console/home/login" );
request.Content = new StringContent( "{\"login\":\"" + TestInitialization.Login + "\",\"password\":\"" + TestInitialization.Password + "\"}",Encoding.UTF8,"application/json" );
Auth_Token = client.SendAsync( request ).GetAwaiter().GetResult().Headers.GetValues( "auth-key" ).ToArray()[ 0 ];
return Auth_Token;
}
这是我的代码的一部分。当执行静态构造函数并且我尝试获取 Auth-Key
属性时 - 在 getter 中它会在检查 null 时循环。
我该如何实现这个逻辑? (无需添加额外的私有字段)
如果值为 null,则执行 set
块。或者带有返回值的 LoginAndGetToken()
方法。
解决方法
internal static String Auth_Token
{
get
{
if( Auth_Token != null )
return Auth_Token;
else
return LoginAndGetToken();
}
set
{
Auth_Token = LoginAndGetToken();
}
}
有两种堆栈溢出情况。
第一个在 get
(return Auth_Token
) 中,另一个在 set
中(LoginAndGetToken
方法设置 Auth_Token
值)
我想建议将 Lazy<T>
与工厂一样使用
internal static Lazy<String> Auth_Token = new Lazy<String>(LoginAndGetToken);
internal static String LoginAndGetToken()
{
HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post,$"{URL_BASE_ADRESS}/console/home/login" );
request.Content = new StringContent( "{\"login\":\"" + TestInitialization.Login + "\",\"password\":\"" + TestInitialization.Password + "\"}",Encoding.UTF8,"application/json" );
return client.SendAsync( request ).GetAwaiter().GetResult().Headers.GetValues( "auth-key" ).ToArray()[ 0 ];
}
这可以像下面这样使用 Auth_Token.Value
来调用:
client.DefaultRequestHeaders.Add( "auth-key",Auth_Token.Value );
PS no additional field 条件看起来很奇怪(而且 Auth_Token
不是字段而是属性)
PPS 是作业吗?有方法数量限制吗?您可以拥有一个 Auth_Token
属性来存储字符串值,而方法 GetAuth_Token()
可以返回 Auth_Token
或在没有 LoginAndGetToken
值时调用 Auth_Token
>
string GetAuth_Token()
{
return Auth_Token = Auth_Token ?? LoginAndGetToken();
}
,
当使用快捷方式属性实现时,例如:
public string MyProp { get; set; }
底层字段是隐式创建的。
但是当提供访问器的任何实现时,不会创建这个隐式字段。如果属性需要保持任何状态,您必须自己定义所需的字段,例如:
public string MyProp
{
get
{
if (myProp == null)
myProp = SomeCodeToComputeMyProp();
return myProp;
}
set
{
myProp = value;
}
}
private string myProp = null;
附加说明:
- setter 应该使用(隐式)
value
参数并基于它设置属性。虽然它做一些额外的检查和计算是完全有效的,但它不应该做一些完全不同的事情。忽略value
并做一些与您完全不同的事情表明您的设计存在很大问题。也许根本不应该有二传手?还是只在课堂上使用的私人课程? - 当属性访问器执行昂贵或阻塞的任务时,从您的类客户端的角度来看,这会令人困惑且容易出错。 HTTP 请求应该在普通方法中而不是在属性中执行。
而 oleksa 是正确的:在这种情况下,您可能仍然需要 Lazy<T>
模式。
好的,谢谢大家的好建议,我决定通过一个额外的领域来做同样的事情。答案如下:
private static String _auth_token;
internal static String Auth_Token
{
get
{
if( _auth_token != null )
return _auth_token;
else
return _auth_token = LoginAndGetToken();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。