簡體   English   中英

循環屬性 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;
    }

這是我的代碼的一部分。 當執行 static 構造函數並且我嘗試獲取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沒有額外的字段條件看起來很奇怪(並且Auth_Token不是一個字段它是屬性)

PPS是家庭作業嗎? 有方法數量限制嗎? 您可以擁有一個Auth_Token屬性來存儲字符串值,並使用GetAuth_Token()方法返回Auth_Token或在沒有Auth_Token值時調用LoginAndGetToken

string GetAuth_Token()
{
  return Auth_Token = Auth_Token ?? LoginAndGetToken();
}

使用快捷方式屬性實現時,例如:

public string MyProp { get; set; }

基礎字段是隱式創建的。

但是,當提供訪問器的任何實現時,不會創建此隱式字段。 如果該屬性需要保留任何 state 您必須自己定義所需的字段,例如:

public string MyProp
{
    get
    {
       if (myProp == null)
           myProp = SomeCodeToComputeMyProp();
       return myProp;
    }
    set
    {
        myProp = value;
    }
}
private string myProp = null;

補充說明:

  • 設置器應該使用(隱式) value參數並基於它設置屬性。 雖然它做一些額外的檢查和計算是完全有效的,但它不應該做一些完全不同的事情。 忽略value並做一些與你完全不同的事情表明你的設計有問題。 也許根本不應該有二傳手? 還是僅在您的 class 內使用的私人設備?
  • 當屬性訪問器執行昂貴或阻塞的任務時,從 class 客戶端的角度來看,這會讓人感到困惑和容易出錯。 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();
      }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM