循环 属性 c#
Looped property 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 时循环。
我该如何实现这个逻辑? (不添加额外的私有字段)
如果值为空,则执行 set
块。或具有 return 值的 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>
和 factory like
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没有附加字段条件看起来很奇怪(而且Auth_Token
不是一个字段它是属性)
PPS是作业吗?方法数量有限制吗?你可以有一个 Auth_Token
属性 只是为了存储一个字符串值和方法 GetAuth_Token()
到 return 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
并做一些与您完全不同的事情表明您的设计有问题。也许根本不应该有 setter ?或者只在您的 class? 中使用一个私人的
- 当 属性 访问器执行昂贵或阻塞的任务时,从您的 class 客户端角度来看,这会令人困惑且容易出错。 HTTP 请求应该在普通方法中执行,而不是在属性内部。
并且 是正确的:在这种情况下,您可能仍然需要 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();
}
}
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 时循环。
我该如何实现这个逻辑? (不添加额外的私有字段)
如果值为空,则执行 set
块。或具有 return 值的 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>
和 factory like
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没有附加字段条件看起来很奇怪(而且Auth_Token
不是一个字段它是属性)
PPS是作业吗?方法数量有限制吗?你可以有一个 Auth_Token
属性 只是为了存储一个字符串值和方法 GetAuth_Token()
到 return 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
并做一些与您完全不同的事情表明您的设计有问题。也许根本不应该有 setter ?或者只在您的 class? 中使用一个私人的
- 当 属性 访问器执行昂贵或阻塞的任务时,从您的 class 客户端角度来看,这会令人困惑且容易出错。 HTTP 请求应该在普通方法中执行,而不是在属性内部。
并且 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();
}
}