Получить два результата из другого метода в главном классе приложения, используя 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);
}
}
}
Анонимно:
dynamic Get()
{
return new {Url = "url", Image = "image"};
}
var result = Get();
var url = (string) result.Url;
Хотя, как правило, это лучше подходит для LINQ.