#c# #error-handling #return
#c# #обработка ошибок #Возврат
Вопрос:
Возможно ли вернуть список ИЛИ целое число в методе?
Что-то вроде:
- если это удалось: верните список
- если это не удалось: верните int (который дает номер ошибки) или строку с сообщением об ошибке.
(сбой, как и в случае отсутствия исключений, но значения неверны, например, PointF.X = ниже 0 или наименьшее значение больше 10).
Теперь я делаю это так:
public List<PointF> GetContourInfoFromFile(string a_file)
{
ListContourPoints.Clear();
List<string> textLines = new List<string>();
bool inEntitiesPart = false;
bool inContourPart = false;
try
{
foreach (string str in File.ReadAllLines(a_file))
{
textLines.Add(str);//Set complete file in array
}
for (int i = 0; i < textLines.Count; i )
{
//read complete file and get information and set them in ListContourPoints
}
//Check Coordinate values
for (int i = 0; i < ListContourPoints.Count; i )
{
//Coordinates are below -1!
if (ListContourPoints[i].X < -1 || ListContourPoints[i].Y < -1)
{
ListContourPoints.Clear();
break;
}
//Lowest X coordinate is not below 10!
if (mostLowestXContour(ListContourPoints) > 10)
{
ListContourPoints.Clear();
break;
}
//Lowest Y coordinate is not below 10!
if (mostLowestYContour(ListContourPoints) > 10)
{
ListContourPoints.Clear();
break;
}
}
}
catch (Exception E)
{
string Error = E.Message;
ListContourPoints.Clear();
}
return ListContourPoints;
}
Когда я делаю это так, я знаю, что со значениями te что-то не так.. но не конкретно, что.
Итак, как я могу это решить? Если это невозможно с возвратом списка ИЛИ строки / int, какое лучшее решение?
Комментарии:
1. Рассматривали ли вы возможность самостоятельного создания исключения при сбое проверки, возможно, даже пользовательского исключения, которому вы можете присвоить указанный вами номер ошибки?
2. Да, вам действительно следует создать исключение, если значения находятся вне диапазона. Кроме того, если эти значения вводятся пользователем, у вас должен быть отдельный метод проверки, который вы вызываете для очистки входных данных ПЕРЕД их передачей
GetContourInfoFromFile()
(и этот метод проверки не должен вызывать исключение; он может возвращатьсяnull
при успешном выполнении или в виде строки сообщения об ошибке при сбое).3. Если значения в файле неверны, он должен прекратить нормальное поведение. Исключение — хорошее решение. Но вам нужно убедиться, что исключение перехвачено на более высоком уровне, чтобы сообщить пользователю, что файл неверен.
4. @MatthewWatson Этот метод фактически проверяет значения и проверяет, верны ли они. То, что вы говорите о возврате
null
при сбое, — это именно то, что я делаю сейчас. Дело в том, что я хочу сообщить пользователю, что он сделал неправильно, например, X ниже нуля. или Y выше 10.5. @Bart88 Я действительно имел в виду, если элементы вводятся пользователем через пользовательский интерфейс — если они считываются из файла, то они не вводятся пользователем напрямую — так что исключение в порядке. Однако ваш метод выполняет две вещи: (1) он загружает и анализирует набор данных из файла и (2) проверяет значения в этих данных после их загрузки. Это нарушает SRP, и вы должны разделить его на два метода.
Ответ №1:
Вы можете
Решение 1:
выдайте исключение, если ошибка, и в приведенном выше коде выполните перехват try
Удалите часть catch в вашей функции, и когда вы вызываете свою функцию, сделайте это в try catch следующим образом:
try
{
List<PointF> result = GetContourInfoFromFile(youfile);
}
catch (Exception E)
{
string Error = E.Message;
}
Решение 2:
возвращает объект с Listresult и error в качестве свойства
Комментарии:
1. Я бы выбрал решение 1, потому что, если значения неверны, нормальная обработка должна быть «прекращена».
Ответ №2:
Вместо возврата числа вы можете создать исключение из блока catch, чтобы оно могло быть перехвачено внешним обработчиком исключений.
Вот пример:
public void MainMethod()
{
try
{
var myList = SomeMethod();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); // prints out "SomeMethod failed."
}
}
public List<object> SomeMethod()
{
try
{
int i = 1 1;
// Some process that may throw an exception
List<object> list = new List<object>();
list.Add(1);
list.Add(i);
return list;
}
catch (Exception ex)
{
Exception newEx = new Exception("SomeMethod failed.");
throw newEx;
}
}
Ответ №3:
вы могли бы создать класс-оболочку, который содержит либо значение, либо код ошибки. Пример:
public class Holder<T>
{
private Holder(T value)
{
WasSuccessful = true;
Value = value;
}
private Holder(int errorCode)
{
WasSuccessful = false;
ErrorCode = errorCode;
}
public bool WasSuccessful { get; }
public T Value { get; }
public int ErrorCode { get; }
public static Holder<T> Success(T value)
{
return new Holder<T>(value);
}
public static Holder<T> Fail(int errorCode)
{
return new Holder<T>(errorCode);
}
}
Использование:
public Holder<PointF> MyFunc()
{
try
{
//
return Holder<PointF>.Success(new PointF());
}
catch
{
return Holder<PointF>.Fail(101);
}
}
Ответ №4:
одним из решений было бы вернуть object
public object GetContourInfoFromFile(string a_file)
{
}
и в методе, в котором вы вызываете это, попробуйте выполнить приведение как к int, так и к list и посмотреть, какой из них будет успешным.
более сложным решением было бы иметь класс
public class YourClassName{
public List<PointF> YourList {get; set;} //for success
public int YourVariable {get; set} // for failure
public string YourMEssage {get; set} // for failure
}
и верните этот
public YourClassName GetContourInfoFromFile(string a_file)
{
}