Получить два результата из другого метода в главном классе приложения, используя C#

Я пытаюсь написать код AC#, с помощью которого я хочу получить изображение из веб-API и заголовок изображения из API. Я реализовал метод с именем GetImage и попытался вернуть из него два результата (изображение и заголовок). Однако я написал код, но поскольку я новичок в этой ситуации, я не знаю, что делать в этом случае.

Мой сервисный класс Image, содержащий методы is-

public class ImageService
{
    public string GetImage(string name)
    {                
        string result1;
        string result2;

        using (WebClient client = new WebClient())
        {
            var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+name;
            string requestUrl = string.Format(uri, name);
            var response = client.DownloadString(new Uri(uri));
            var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
            var firstKey = responseJson.query.pages.First().Key;
            result1 = responseJson.query.pages[firstKey].thumbnail.source;
            result2 = responseJson.query.pages[firstKey].title;

            var hash = uri.GetHashCode();

        }
        return result1,result2; //showing error
    }
}

Теперь Form1.cs, где я хочу показать результаты в картинке и ярлык

public partial class Form1 : Form
{
    private readonly ImageService _imageService;
    public Form1()
    {            
        _imageService = new ImageService();
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
        pictureBox1.LoadAsync(_imageService.GetImage(textBox1.Text));
        label1.Text = _imageService.GetImage(textBox1.Text);// not working
    }
}

8 ответов

Решение

Лучший способ - создать новый класс, содержащий необходимые данные, и вернуть его. Таким образом, если вам нужно добавить больше информации, вы можете просто добавить ее в класс.

Например:

public class ImageInfo
{
    public string Title { get; set; }
    public string Image { get; set; }
}

Затем ваш метод возвращает класс:

public ImageInfo GetImage(string name)
{                
    ImageInfo info = new ImageInfo();

    using (WebClient client = new WebClient())
    {
        var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+name;
        string requestUrl = string.Format(uri, name);
        var response = client.DownloadString(new Uri(uri));
        var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
        var firstKey = responseJson.query.pages.First().Key;
        info.Image = responseJson.query.pages[firstKey].thumbnail.source;
        info.Title = responseJson.query.pages[firstKey].title;

        var hash = uri.GetHashCode();

    }
    return info;
}

Вы можете вернуть только 1 значение из функции. Таким образом, для решения этой проблемы у вас есть 2 варианта:

  • Использовать out параметр функции
  • Вернуть пользовательский объект, который имеет 2 свойства

Индивидуальное решение для объекта:

public class ImageResult
{
    string ImageUrl { get; set; }
    string Title { get; set; }
}

public ImageResult GetImage(string imageTitle)
{                
    ImageResult result = new ImageResult();

    using (WebClient client = new WebClient())
    {
        var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+imageTitle;
        string requestUrl = string.Format(uri, imageTitle);
        var response = client.DownloadString(new Uri(uri));
        var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
        var firstKey = responseJson.query.pages.First().Key;

        result.ImageUrl = responseJson.query.pages[firstKey].thumbnail.source;
        result.Title = responseJson.query.pages[firstKey].title;

        var hash = uri.GetHashCode();

    }
    return result;
}

private void button1_Click(object sender, EventArgs e)
{
    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

    var imageResult = _imageService.GetImage(textBox1.Text);

    pictureBox1.LoadAsync(imageResult.ImageUrl);
    label1.Text = imageResult.Title;
}

Есть несколько вариантов на выбор.

Вы можете вернуть словарь так:

        public Dictionary<string, string> GetImage(string name)
        {
            string result1;
            string result2;

            using (WebClient client = new WebClient())
            {
                    var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+name;
                    string requestUrl = string.Format(uri, name);
                    var response = client.DownloadString(new Uri(uri));
                    var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
                    var firstKey = responseJson.query.pages.First().Key;
                    result1 = responseJson.query.pages[firstKey].thumbnail.source;
                    result2 = responseJson.query.pages[firstKey].title;

                    var hash = uri.GetHashCode();

            }
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            dictionary.Add("Source", result1);
            dictionary.Add("Title", result2);
            return dictionary;
        }

Тогда вы можете использовать словарь так:

    private void button1_Click(object sender, EventArgs e)
    {
        pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
        Dictionary<string, string> imageDictionary = _imageService.GetImage(textBox1.Text);
        pictureBox1.LoadAsync(imageDictionary["Source"]);
        label1.Text = imageDictionary["Title"];
    }

Вы также можете вернуть List или использовать параметр out, или, как отмечено в других ответах, вы можете создать собственный класс и вернуть его.

Вы не можете вернуть несколько значений из такого метода.

Измените профиль метода на:

private Tuple<string, string> GetImage(string name)

и заявление возврата:

return new Tuple<string, string>(result1, result2);

Затем вы можете получить каждый результат из кортежа:

var resultTuple = _imageService.GetImage(textBox1.Text);
label1.Text = resultTuple.Item1;
label2.Text = resultTuple.Item2;

Поскольку метод может иметь только одно возвращаемое значение, вы можете использовать out параметр для возврата дополнительного значения.

public string GetImage(string name, out string title)
{
    string result1;

    using (WebClient client = new WebClient())
    {
        var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+name;
        string requestUrl = string.Format(uri, name);
        var response = client.DownloadString(new Uri(uri));
        var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
        var firstKey = responseJson.query.pages.First().Key;
        result1 = responseJson.query.pages[firstKey].thumbnail.source;
        title = responseJson.query.pages[firstKey].title;

        var hash = uri.GetHashCode();
     }
     return result1;
 }

Использование;

private void button1_Click(object sender, EventArgs e)
{
     string title = string.Empty;

     pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
     pictureBox1.LoadAsync(_imageService.GetImage(textBox1.Text, out title));
     label1.Text = title;
}

Вы можете использовать класс:

public class Image
{
    public string Url { get; internal set; }
    public string Title { get; internal set; }

    public Image(string name)
    {
       string result1;
       string result2;

        using (WebClient client = new WebClient())
        {
            var uri = "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=pageimages&pithumbsize=400&titles="+name;
            string requestUrl = string.Format(uri, name);
            var response = client.DownloadString(new Uri(uri));
            var responseJson = JsonConvert.DeserializeObject<ImgRootobject>(response);
            var firstKey = responseJson.query.pages.First().Key;
            result1 = responseJson.query.pages[firstKey].thumbnail.source;
            result2 = responseJson.query.pages[firstKey].title;

            var hash = uri.GetHashCode();

        }
        Url = result1;
        Title = result2;
    }
}

И используйте это так:

private void button1_Click(object sender, EventArgs e)
{
    var img = _imageService.GetImage(textBox1.Text);

    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
    pictureBox1.LoadAsync(img.Url);
    label1.Text = img.Title;
}

Использование кортежей.пример

using System;

class Program
{
    static void Main()
    {
    // Create three-item tuple.
    Tuple<int, string, bool> tuple =
        new Tuple<int, string, bool>(1, "cat", true);
    // Access tuple properties.
    if (tuple.Item1 == 1)
    {
        Console.WriteLine(tuple.Item1);
    }
    if (tuple.Item2 == "dog")
    {
        Console.WriteLine(tuple.Item2);
    }
    if (tuple.Item3)
    {
        Console.WriteLine(tuple.Item3);
    }
    }
}

шрифт http://www.dotnetperls.com/tuple

Анонимно:

dynamic Get()
{
    return new {Url = "url", Image = "image"};
}

var result = Get();

var url = (string) result.Url;

Хотя, как правило, это лучше подходит для LINQ.

Другие вопросы по тегам