Как передать var в другой класс
Переменную var нельзя сделать публичной, а это значит ее нельзя вызвать в другом классе.
У меня 2 класса, в одном есть переменная var, а в другом нужно к ней обратиться, как поступить?
private void Button_Click_8(object sender, RoutedEventArgs e)
{
dg2.ItemsSource = me.ToList();
}
class ExcelImportSheet
{
internal class Metric
{
public int IDОбращения { get; set; }
public string IdКлиента { get; set; }
public string ФИО { get; set; }
public string Email { get; set; }
public string Услуга { get; set; }
public string Статус { get; set; }
public string ОценкаКлиента { get; set; }
}
public IEnumerable<Metric> EnumerateMetrics(string xlsxpath)
{
var openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
if (openFileDialog.ShowDialog() == true)
{
var excelFilePath = openFileDialog.FileName;
}
using (var excelFilePath = new XLWorkbook(xlsxpath))
using (var worksheet = excelFilePath.Worksheets.Worksheet(1))
{
for (int row = 2; row <= 10; ++row)
{
var me = new Metric
{
IDОбращения = excelFilePath.Cell("A5:A100").GetValue<int>(),
IdКлиента = excelFilePath.Cell("B5:B100").GetValue<string>(),
ФИО = excelFilePath.Cell("C5:C100").GetValue<string>(),
Email = excelFilePath.Cell("D5:D100").GetValue<string>(),
Услуга = excelFilePath.Cell("E5:E100").GetValue<string>(),
Статус = excelFilePath.Cell("F5:F100").GetValue<string>(),
ОценкаКлиента = excelFilePath.Cell("G5:G100").GetValue<string>(),
};
yield return me;
}
}
}
}
Ответы (1 шт):
Никак. Локальная переменная на то и локальная, что к ней никак нельзя получить доступ извне.
Проиллюстрирую вопрос, к примеру есть 2 класса, в одном из них метод с локальной переменной:
class MyClass
{
public void MyMethod()
{
int x = 42;
}
}
class AnotherClass
{
public void MyMethod()
{
MessageBox.Show(x); // ОШИБКА! где взять "x"?
}
}
Допустим вы хотите запустить этот код так:
var obj1 = new MyClass();
obj1.MyMethod();
var obj2 = new AnotherClass();
obj2.MyMethod();
Проиллюстрирую несколько способов решения.
Возвращаемое значение и передача аргумента
class MyClass
{
public int MyMethod()
{
int x = 42;
return x;
}
}
class AnotherClass
{
public void MyMethod(int x)
{
MessageBox.Show(x);
}
}
var obj1 = new MyClass();
int x = obj1.MyMethod();
var obj2 = new AnotherClass();
obj2.MyMethod(x);
Здесь передача простая, через вызывающий код.
Публичное поле и передача в конструктор
class MyClass
{
public int x;
public void MyMethod()
{
x = 42;
}
}
class AnotherClass
{
private MyClass _mc;
public AnotherClass(MyClass mc)
{
_mc = mc;
}
public void MyMethod()
{
MessageBox.Show(_mc.x);
}
}
var obj1 = new MyClass();
obj1.MyMethod();
var obj2 = new AnotherClass(obj1);
obj2.MyMethod();
Здесь экземпляр класса AnotherClass полностью получает доступ ко всем публичным членам экземпляра MyClass - не только полям, но и методам. Еще говорят, "AnotherClass имеет зависимость от MyClass".
Статическое публичное поле (НЕ РЕКОМЕНДУЕТСЯ)
class MyClass
{
public static int x;
public void MyMethod()
{
x = 42;
}
}
class AnotherClass
{
public void MyMethod()
{
MessageBox.Show(MyClass.x);
}
}
var obj1 = new MyClass();
obj1.MyMethod();
var obj2 = new AnotherClass();
obj2.MyMethod();
Несмотря на простоту, это наихудший вариант решения задачи, но я был должен показать, что он есть. Главная его проблема, что данный подход несовместим с ООП. То есть если у вас будет более одного экземпляра MyClass, то что-нибудь сломается, потому что статические члены класса - общие для всех экземпляров. Статику нужно использовать с умом и только тогда, когда она нужна осознанно, и без неё никак.
Ваш случай решается простым созданием экземпляра второго класса прямо в нужном методе.
class MyClass
{
public void MyMethod()
{
var obj = new ExcelImportSheet();
dg.ItemsSource = obj.EnumerateMetrics();
}
}
class ExcelImportSheet
{
public IEnumerable<Metric> EnumerateMetrics()
{
// ...
yield return me;
}
}
Либо так, чтобы не создавать новый объект на каждый вызов метода.
class MyClass
{
private ExcelImportSheet _obj = new ExcelImportSheet();
public void MyMethod()
{
dg.ItemsSource = _obj.EnumerateMetrics();
}
}
class ExcelImportSheet
{
public IEnumerable<Metric> EnumerateMetrics()
{
// ...
yield return me;
}
}
.ToList() вызывать не нужно, это лишнее, DataGrid поддерживает IEnumerable<T>.
Окей, вот полный пример, как бы я написал, исправив все ошибки
private ExcelImportSheet _eis = new ExcelImportSheet();
private void Button_Click_8(object sender, RoutedEventArgs e)
{
var openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
if (openFileDialog.ShowDialog())
{
string path = openFileDialog.FileName;
dg2.ItemsSource = _eis.EnumerateMetrics(path);
}
}
internal class Metric
{
public int IDОбращения { get; set; }
public string IdКлиента { get; set; }
public string ФИО { get; set; }
public string Email { get; set; }
public string Услуга { get; set; }
public string Статус { get; set; }
public string ОценкаКлиента { get; set; }
}
class ExcelImportSheet
{
public IEnumerable<Metric> EnumerateMetrics(string xlsxpath)
{
using (var workbook = new XLWorkbook(xlsxpath))
using (var worksheet = workbook.Worksheets.Worksheet(1))
{
for (int row = 3; row <= 5; ++row)
{
var me = new Metric
{
IDОбращения = worksheet.Cell($"A{row}").GetValue<int>(),
IdКлиента = worksheet.Cell($"B{row}").GetValue<string>(),
ФИО = worksheet.Cell($"C{row}").GetValue<string>(),
Email = worksheet.Cell($"D{row}").GetValue<string>(),
Услуга = worksheet.Cell($"E{row}").GetValue<string>(),
Статус = worksheet.Cell($"F{row}").GetValue<string>(),
ОценкаКлиента = worksheet.Cell($"G{row}").GetValue<string>(),
};
yield return me;
}
}
}
}