You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WebAPI类变量跨类引用及WinForm汇率更新实现咨询

Hey there! Let's walk through building that exchange rate service for your Windows Forms app, and clear up how to share those rate values across multiple forms.

Step 1: Build a Shared Exchange Rate Service

Since you need to fetch rates once at startup and reuse them across forms, a singleton class is perfect here—it ensures only one instance of the service exists, so you don't make duplicate API calls, and all forms can access the same rate data.

Here's a complete example of the service class:

using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public class ExchangeRateService
{
    // Singleton instance (only one exists app-wide)
    private static readonly ExchangeRateService _sharedInstance = new ExchangeRateService();
    
    // Private fields to store the rates (only modifiable within this class)
    private decimal _gbpToEur;
    private decimal _eurToGbp;

    // Private constructor to prevent external instantiation
    private ExchangeRateService() {}

    // Public read-only properties to let other classes access the rates
    public decimal GbpToEurRate => _gbpToEur;
    public decimal EurToGbpRate => _eurToGbp;

    // Get the singleton instance
    public static ExchangeRateService GetInstance()
    {
        return _sharedInstance;
    }

    // Fetch latest rates from your Web API
    public async Task LoadLatestRatesAsync()
    {
        try
        {
            using var httpClient = new HttpClient();
            // Replace with your actual API endpoint (adjust the JSON parsing to match your API's response)
            var apiResponse = await httpClient.GetStringAsync("https://your-exchange-api.com/latest?base=GBP");
            
            // Parse the JSON response (using System.Text.Json here; Newtonsoft.Json works too)
            var rateData = JsonSerializer.Deserialize<ExchangeRateResponse>(apiResponse);
            
            // Update the private rate fields
            _gbpToEur = rateData.EurRate;
            _eurToGbp = Math.Round(1 / _gbpToEur, 4); // Calculate reverse rate
        }
        catch (Exception ex)
        {
            // Handle API errors (log, show a message, use fallback rates, etc.)
            Console.WriteLine($"Failed to load rates: {ex.Message}");
            _gbpToEur = 1.17m; // Fallback rate if API fails
            _eurToGbp = 0.85m;
        }
    }

    // Helper class to match your API's JSON structure (adjust as needed)
    private class ExchangeRateResponse
    {
        [JsonPropertyName("rates")]
        public Rates Rates { get; set; }
        
        // Shortcut to get EUR rate directly
        public decimal EurRate => Rates.EUR;
    }

    private class Rates
    {
        [JsonPropertyName("EUR")]
        public decimal EUR { get; set; }
    }
}
Step 2: Initialize the Service at App Startup

You want to fetch rates before your forms load, so update your Program.cs to run the async load method first:

using System;
using System.Threading.Tasks;
using System.Windows.Forms;

static class Program
{
    [STAThread]
    static async Task Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // Initialize the rate service and fetch latest data
        var rateService = ExchangeRateService.GetInstance();
        await rateService.LoadLatestRatesAsync();

        // Launch your main form
        Application.Run(new MainForm());
    }
}
Step 3: Access Rates from Any Form

Now any form in your app can grab the singleton instance and use the rates:

// Example in a conversion form
private void ConvertButton_Click(object sender, EventArgs e)
{
    var rateService = ExchangeRateService.GetInstance();
    
    if (decimal.TryParse(AmountTextBox.Text, out decimal amount))
    {
        decimal convertedAmount = FromCurrencyComboBox.SelectedItem.ToString() == "GBP" 
            ? amount * rateService.GbpToEurRate 
            : amount * rateService.EurToGbpRate;
        
        ResultLabel.Text = $"{amount} {FromCurrencyComboBox.SelectedItem} = {convertedAmount:F2} {ToCurrencyComboBox.SelectedItem}";
    }
}
Answering Your Core Question: Sharing Variables Between Classes

To create variables in a class that other classes can access, follow these core principles:

  • Encapsulate private data: Store the raw values in private fields (_gbpToEur) so they can't be modified directly from outside the class—this keeps your rate data consistent.
  • Expose public read-only properties: Use public decimal GbpToEurRate => _gbpToEur; to let other classes read the value without changing it.
  • Use a singleton or static class for global access: If you need the same data across the entire app, a singleton (like the example above) ensures all forms use the same rate values. Alternatively, you could use a static class, but singletons are better if you need to run initialization logic (like fetching from the API).
Bonus Tips
  • Handle API failures: Always add error handling (like the try/catch in the service) so your app doesn't crash if the API is down.
  • Add rate updates: If you want to refresh rates periodically, add a Timer to the service class that calls LoadLatestRatesAsync every hour or so.
  • Thread safety: If you're updating rates while the app is running, use a lock around the rate fields to prevent race conditions (since Windows Forms uses a single UI thread, this is mostly needed if you're updating rates in background tasks).

内容的提问来源于stack exchange,提问作者Isabelle May

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:57:45