Могу ли я установить Ubuntu на логический раздел? Каковы будут преимущества или недостатки использования логического раздела для установки Ubuntu 12.04?

Он возвращает true, потому что для Javascript это определенный объект, поэтому не false, и jQuery всегда будет давать вам новый объект независимо от того, найден ли этот элемент или нет - однако длина массива будет равна нулю, например

$("span").length

Если у вас нет , это будет ноль, но может быть 1 или более.

Вы можете написать свой собственный плагин, чтобы избежать повторения if, как плагин JQuery, как я сделал для этот . Это довольно легко сделать:

(function($)
{
        /* Checks if a jQuery object exists in the DOM, by checking the length of its child elements. */
        $.fn.elementExists = function()
        {
                ///     
                ///     Checks if a jQuery object exists in the DOM, by checking the length of its child elements.
                ///     
                ///     
                return jQuery(this).length > 0;
        };
})(jQuery);

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

if ($("#someid").elementExists())
{

}

9
задан Mark Amery 18 October 2017 в 12:39
поделиться

28 ответов

Выгода System.Exception и включает типы

catch (Exception ex)            
{                
    if (ex is FormatException || ex is OverflowException)
    {
        WebId = Guid.Empty;
        return;
    }

    throw;
}
1956
ответ дан Joe 18 October 2017 в 12:39
поделиться

Нет никакого преимущества или недостатка установки Ubuntu на основном или логическом разделе. Единственный "недостаток", если можно назвать это тем путем, состоит в том, что, если Вы выбираете логичный, названия/dev/sd запустятся в 5. Но если Вы выберете основной, то они запустят по телефону 1.

, Например:

Основной

/dev/sda1
/dev/sda2
...

Логичный

/dev/sda5
/dev/sda6
...

В основном ничто для волнения о.

Насколько я вижу, Вы хороши для движения, устанавливая Ubuntu на тех 55 ГБ пространства, которое Вы оставили в своем логическом пространстве. Тот, который я имею в виду, является этим:

enter image description here

Так никакая потребность волноваться об этом. Просто установите его и наслаждайтесь.

15
ответ дан Luis Alvarado 22 October 2019 в 14:05
поделиться

Может быть, постараться сохранить свой код простым, например, помещая общий код в метод, как вы это делали бы в любой другой части кода, не входящей в предложение catch?

Например:

try
{
    // ...
}
catch (FormatException)
{
    DoSomething();
}
catch (OverflowException)
{
    DoSomething();
}

// ...

private void DoSomething()
{
    // ...
}

Как бы я это ни делал, пытаясь найти простой, красивый паттерн

4
ответ дан Żubrówka 18 October 2017 в 12:39
поделиться

Хотел добавить мой короткий ответ в эту и без того длинную ветку. Кое-что, что не было упомянуто, является порядком приоритета операторов catch, более конкретно, вам необходимо знать область действия каждого типа исключения, которое вы пытаетесь перехватить.

Например, если вы используете исключение «catch-all» в качестве Exception , оно будет предшествовать всем остальным операторам catch, и вы, очевидно, получите ошибки компилятора, однако, если вы измените порядок в обратном порядке, вы можете связать свои выражения catch (немного анти-паттерна, я думаю), вы можете поместить тип catch-all Exception внизу, и это будет захватывать любые исключения, которые не обслуживали более высокий уровень в вашем блоке try..catch :

            try
            {
                // do some work here
            }
            catch (WebException ex)
            {
                // catch a web excpetion
            }
            catch (ArgumentException ex)
            {
                // do some stuff
            }
            catch (Exception ex)
            {
                // you should really surface your errors but this is for example only
                throw new Exception("An error occurred: " + ex.Message);
            }

Я настоятельно рекомендую людям ознакомиться с этим документом MSDN:

Иерархия исключений

4
ответ дан Tahir Khalid 18 October 2017 в 12:39
поделиться
catch (Exception ex)
{
    if (!(
        ex is FormatException ||
        ex is OverflowException))
    {
        throw;
    }
    Console.WriteLine("Hello");
}
12
ответ дан mantale 18 October 2017 в 12:39
поделиться

Если вам удастся обновить приложение до C # 6, вам повезет. В новой версии C # реализованы фильтры исключений. Таким образом, вы можете написать это:

catch (Exception ex) when (ex is FormatException || ex is OverflowException) {
    WebId = Guid.Empty;
}

Некоторые люди думают, что этот код такой же, как

catch (Exception ex) {                
    if (ex is FormatException || ex is OverflowException) {
        WebId = Guid.Empty;
    }
    throw;
}

Но это не так. На самом деле это единственная новая функция в C # 6, которую невозможно эмулировать в предыдущих версиях. Во-первых, повторный бросок означает больше накладных расходов, чем пропуск улова. Во-вторых, это не семантически эквивалентно. Новая функция сохраняет стек без изменений при отладке кода. Без этой функции аварийный дамп менее полезен или даже бесполезен.

См. обсуждение этого на CodePlex . И пример , показывающий разницу .

72
ответ дан Maniero 18 October 2017 в 12:39
поделиться

Фильтры исключений теперь доступны в c # 6+. Вы можете сделать

try
{
       WebId = new Guid(queryString["web"]);
}
catch (Exception ex) when(ex is FormatException || ex is OverflowException)
{
     WebId = Guid.Empty;
}

В C # 7.0+ вы также можете комбинировать это с сопоставлением с образцом

try
{
   await Task.WaitAll(tasks);
}
catch (Exception ex) when( ex is AggregateException ae &&
                           ae.InnerExceptions.Count > tasks.Count/2)
{
   //More than half of the tasks failed maybe..? 
}
65
ответ дан Mat J 18 October 2017 в 12:39
поделиться

@Micheal

Немного переработанная версия вашего кода:

catch (Exception ex)
{
   Type exType = ex.GetType();
   if (exType == typeof(System.FormatException) || 
       exType == typeof(System.OverflowException)
   {
       WebId = Guid.Empty;
   } else {
      throw;
   }
}

Сравнение строк уродливо и медленно.

16
ответ дан Michael Stum 18 October 2017 в 12:39
поделиться

В c # 6.0 Фильтры исключений улучшены для обработки исключений

try
{
    DoSomeHttpRequest();
}
catch (System.Web.HttpException e)
{
    switch (e.GetHttpCode())
    {
        case 400:
            WriteLine("Bad Request");
        case 500:
            WriteLine("Internal Server Error");
        default:
            WriteLine("Generic Error");
    }
}
-22
ответ дан Kashif 18 October 2017 в 12:39
поделиться

К сожалению, не в C #, поскольку для этого вам понадобится фильтр исключений, а C # не раскрывает эту функцию MSIL. VB.NET имеет такую ​​возможность, например,

Catch ex As Exception When TypeOf ex Is FormatException OrElse TypeOf ex Is OverflowException

То, что вы можете сделать, это использовать анонимную функцию для инкапсуляции вашего кода ошибки, а затем вызывать его в тех конкретных блоках перехвата:

Action onError = () => WebId = Guid.Empty;
try
{
    // something
}
catch (FormatException)
{
    onError();
}
catch (OverflowException)
{
    onError();
}
185
ответ дан Greg Beech 18 October 2017 в 12:39
поделиться

Обратите внимание, что я нашел один способ сделать это, но это больше похоже на материал для The Daily WTF :

catch (Exception ex)
{
    switch (ex.GetType().Name)
    {
        case "System.FormatException":
        case "System.OverflowException":
            WebId = Guid.Empty;
            break;
        default:
            throw;
    }
}
1
ответ дан 3 revs, 3 users 61% 18 October 2017 в 12:39
поделиться

Как насчет

try
{
    WebId = Guid.Empty;
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
}
catch (OverflowException)
{
}
13
ответ дан Sepster 18 October 2017 в 12:39
поделиться

в C # 6 рекомендуется использовать фильтры исключений, вот пример:

 try
 {
      throw new OverflowException();
 }
 catch(Exception e ) when ((e is DivideByZeroException) || (e is OverflowException))
 {
       // this will execute iff e is DividedByZeroEx or OverflowEx
       Console.WriteLine("E");
 }
18
ответ дан SHM 18 October 2017 в 12:39
поделиться

Обновление 2015-12-15: см. https://stackoverflow.com/a/22864936/1718702 для C # 6. Это чище и теперь стандарт в языке.

Для тех, кто хочет, чтобы было более элегантное решение , чтобы перехватывать один раз и фильтровать исключения, я использую метод расширения, как показано ниже.

У меня уже было это расширение в моей библиотеке, изначально написанное для других целей, но оно отлично работало для type проверки исключений. Плюс, имхо, это выглядит чище, чем куча || утверждений. Кроме того, в отличие от принятого ответа, я предпочитаю явную обработку исключений, поэтому ex is ... имел нежелательное поведение, поскольку производные классы присваиваются родительским типам).

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

if (ex.GetType().IsAnyOf(
    typeof(FormatException),
    typeof(ArgumentException)))
{
    // Handle
}
else
    throw;

Расширение IsAnyOf.cs (см. Пример полной обработки ошибок для зависимостей)

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter matches at least one of the passed in comparisons.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_comparisons">Values to compare against.</param>
        /// <returns>True if a match is found.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static bool IsAnyOf<T>(this T p_parameter, params T[] p_comparisons)
        {
            // Validate
            p_parameter
                .CannotBeNull("p_parameter");
            p_comparisons
                .CannotBeNullOrEmpty("p_comparisons");

            // Test for any match
            foreach (var item in p_comparisons)
                if (p_parameter.Equals(item))
                    return true;

            // Return no matches found
            return false;
        }
    }
}

Пример полной обработки ошибок (копирование-вставка в новое консольное приложение)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.FluentValidation;

namespace IsAnyOfExceptionHandlerSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // High Level Error Handler (Log and Crash App)
            try
            {
                Foo();
            }
            catch (OutOfMemoryException ex)
            {
                Console.WriteLine("FATAL ERROR! System Crashing. " + ex.Message);
                Console.ReadKey();
            }
        }

        static void Foo()
        {
            // Init
            List<Action<string>> TestActions = new List<Action<string>>()
            {
                (key) => { throw new FormatException(); },
                (key) => { throw new ArgumentException(); },
                (key) => { throw new KeyNotFoundException();},
                (key) => { throw new OutOfMemoryException(); },
            };

            // Run
            foreach (var FooAction in TestActions)
            {
                // Mid-Level Error Handler (Appends Data for Log)
                try
                {
                    // Init
                    var SomeKeyPassedToFoo = "FooParam";

                    // Low-Level Handler (Handle/Log and Keep going)
                    try
                    {
                        FooAction(SomeKeyPassedToFoo);
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType().IsAnyOf(
                            typeof(FormatException),
                            typeof(ArgumentException)))
                        {
                            // Handle
                            Console.WriteLine("ex was {0}", ex.GetType().Name);
                            Console.ReadKey();
                        }
                        else
                        {
                            // Add some Debug info
                            ex.Data.Add("SomeKeyPassedToFoo", SomeKeyPassedToFoo.ToString());
                            throw;
                        }
                    }
                }
                catch (KeyNotFoundException ex)
                {
                    // Handle differently
                    Console.WriteLine(ex.Message);

                    int Count = 0;
                    if (!Validate.IsAnyNull(ex, ex.Data, ex.Data.Keys))
                        foreach (var Key in ex.Data.Keys)
                            Console.WriteLine(
                                "[{0}][\"{1}\" = {2}]",
                                Count, Key, ex.Data[Key]);

                    Console.ReadKey();
                }
            }
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter matches at least one of the passed in comparisons.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_comparisons">Values to compare against.</param>
        /// <returns>True if a match is found.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static bool IsAnyOf<T>(this T p_parameter, params T[] p_comparisons)
        {
            // Validate
            p_parameter
                .CannotBeNull("p_parameter");
            p_comparisons
                .CannotBeNullOrEmpty("p_comparisons");

            // Test for any match
            foreach (var item in p_comparisons)
                if (p_parameter.Equals(item))
                    return true;

            // Return no matches found
            return false;
        }

        /// <summary>
        /// Validates if any passed in parameter is equal to null.
        /// </summary>
        /// <param name="p_parameters">Parameters to test for Null.</param>
        /// <returns>True if one or more parameters are null.</returns>
        public static bool IsAnyNull(params object[] p_parameters)
        {
            p_parameters
                .CannotBeNullOrEmpty("p_parameters");

            foreach (var item in p_parameters)
                if (item == null)
                    return true;

            return false;
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter is not null, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void CannotBeNull(this object p_parameter, string p_name)
        {
            if (p_parameter == null)
                throw
                    new
                        ArgumentNullException(
                        string.Format("Parameter \"{0}\" cannot be null.",
                        p_name), default(Exception));
        }
    }
}

namespace Common.FluentValidation
{
    public static partial class Validate
    {
        /// <summary>
        /// Validates the passed in parameter is not null or an empty collection, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static void CannotBeNullOrEmpty<T>(this ICollection<T> p_parameter, string p_name)
        {
            if (p_parameter == null)
                throw new ArgumentNullException("Collection cannot be null.\r\nParameter_Name: " + p_name, default(Exception));

            if (p_parameter.Count <= 0)
                throw new ArgumentOutOfRangeException("Collection cannot be empty.\r\nParameter_Name: " + p_name, default(Exception));
        }

        /// <summary>
        /// Validates the passed in parameter is not null or empty, throwing a detailed exception message if the test fails.
        /// </summary>
        /// <param name="p_parameter">Parameter to validate.</param>
        /// <param name="p_name">Name of tested parameter to assist with debugging.</param>
        /// <exception cref="ArgumentException"></exception>
        public static void CannotBeNullOrEmpty(this string p_parameter, string p_name)
        {
            if (string.IsNullOrEmpty(p_parameter))
                throw new ArgumentException("String cannot be null or empty.\r\nParameter_Name: " + p_name, default(Exception));
        }
    }
}

Два примера модульных тестов NUnit

Соответствие поведения для типов Exception: точный (т. е. дочерний элемент НЕ соответствует ни одному из родительских типов).

using System;
using System.Collections.Generic;
using Common.FluentValidation;
using NUnit.Framework;

namespace UnitTests.Common.Fluent_Validations
{
    [TestFixture]
    public class IsAnyOf_Tests
    {
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void IsAnyOf_ArgumentNullException_ShouldNotMatch_ArgumentException_Test()
        {
            Action TestMethod = () => { throw new ArgumentNullException(); };

            try
            {
                TestMethod();
            }
            catch (Exception ex)
            {
                if (ex.GetType().IsAnyOf(
                    typeof(ArgumentException), /*Note: ArgumentNullException derrived from ArgumentException*/
                    typeof(FormatException),
                    typeof(KeyNotFoundException)))
                {
                    // Handle expected Exceptions
                    return;
                }

                //else throw original
                throw;
            }
        }

        [Test, ExpectedException(typeof(OutOfMemoryException))]
        public void IsAnyOf_OutOfMemoryException_ShouldMatch_OutOfMemoryException_Test()
        {
            Action TestMethod = () => { throw new OutOfMemoryException(); };

            try
            {
                TestMethod();
            }
            catch (Exception ex)
            {
                if (ex.GetType().IsAnyOf(
                    typeof(OutOfMemoryException),
                    typeof(StackOverflowException)))
                    throw;

                /*else... Handle other exception types, typically by logging to file*/
            }
        }
    }
}
9
ответ дан Community 18 October 2017 в 12:39
поделиться

Это классическая проблема, с которой сталкивается каждый разработчик C #.

Позвольте мне разбить ваш вопрос на 2 вопроса. Первый,

Можно ли поймать несколько исключений одновременно?

Короче говоря, нет.

Что приводит к следующему вопросу,

Как мне избежать написания дублирующего кода, если я не могу перехватить несколько типов исключений в одном блоке catch ()?

Учитывая ваш конкретный пример, где резервное значение дешево построить, я хотел бы выполнить следующие шаги:

  1. Инициализировать WebId в качестве запасного значения.
  2. Создайте новый Guid во временной переменной.
  3. Установите для WebId полностью созданную временную переменную. Сделайте это последним утверждением блока try {}.

Таким образом, код выглядит следующим образом:

try
{
    WebId = Guid.Empty;
    Guid newGuid = new Guid(queryString["web"]);
    // More initialization code goes here like 
    // newGuid.x = y;
    WebId = newGuid;
}
catch (FormatException) {}
catch (OverflowException) {}

Если выбрасывается какое-либо исключение, то WebId никогда не устанавливается на половину построенного значения и остается Guid.Empty.

Если построение запасного значения стоит дорого, а сброс значения намного дешевле, я бы переместил код сброса в его собственную функцию:

try
{
    WebId = new Guid(queryString["web"]);
    // More initialization code goes here.
}
catch (FormatException) {
    Reset(WebId);
}
catch (OverflowException) {
    Reset(WebId);
}
7
ответ дан Jeffrey Rennie 18 October 2017 в 12:39
поделиться

С помощью C # 7 ответ от Майкла Стума может быть улучшен при сохранении читабельности оператора switch:

catch (Exception ex)
{
    switch (ex)
    {
        case FormatException _:
        case OverflowException _:
            WebId = Guid.Empty;
            break;
        default:
            throw;
    }
}
20
ответ дан Fabian 18 October 2017 в 12:39
поделиться

Принятый ответ кажется приемлемым, за исключением того, что CodeAnalysis / FxCop будет жаловаться на тот факт, что он перехватывает общий тип исключения.

Кроме того, кажется, что оператор is может слегка ухудшить производительность.

CA1800: не приводите без необходимости говорит «подумайте о проверке результата вместо оператора as», но если вы сделаете это, вы будете писать больше кода чем если вы поймаете каждое исключение в отдельности.

Во всяком случае, вот что я хотел бы сделать:

bool exThrown = false;

try
{
    // Something
}
catch (FormatException) {
    exThrown = true;
}
catch (OverflowException) {
    exThrown = true;
}

if (exThrown)
{
    // Something else
}
18
ответ дан Peter Mortensen 18 October 2017 в 12:39
поделиться

Ответ Джозефа Дейгла является хорошим решением, но я обнаружил, что следующая структура немного более аккуратна и менее подвержена ошибкам.

catch(Exception ex)
{   
    if (!(ex is SomeException || ex is OtherException)) throw;

    // Handle exception
}

Есть несколько преимуществ инвертирования выражения:

  • В выражении возврата нет необходимости
  • Код не является вложенным
  • нет риска забыть утверждения «throw» или «return», которые в решении Иосифа отделены от выражения.

Его можно даже сжать в одну строку (хотя и не очень красиво)

catch(Exception ex) { if (!(ex is SomeException || ex is OtherException)) throw;

    // Handle exception
}

Редактировать: Фильтрация исключений в C # 6.0 синтаксис станет немного чище и будет иметь ряд других преимуществ по сравнению с любым текущим решением. (прежде всего оставляя стек без повреждений)

Вот как будет выглядеть та же проблема с использованием синтаксиса C # 6.0:

catch(Exception ex) when (ex is SomeException || ex is OtherException)
{
    // Handle exception
}
17
ответ дан Community 18 October 2017 в 12:39
поделиться

Если вы не хотите использовать оператор if в пределах catch областей, в C# 6.0, вы можете использовать синтаксис Exception Filters , который уже поддерживается CLR в предварительных версиях, но существовал только в VB.NET / MSIL:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (Exception exception) when (exception is FormatException || ex is OverflowException)
{
    WebId = Guid.Empty;
}

Этот код будет перехватывать Exception только тогда, когда это InvalidDataException или ArgumentNullException.

На самом деле, вы можете поместить любое условие в это предложение when:

static int a = 8;

...

catch (Exception exception) when (exception is InvalidDataException && a == 8)
{
    Console.WriteLine("Catch");
}

Обратите внимание, что в отличие от оператора if внутри области действия catch, Exception Filters не может throw Exceptions, и когда они делают, или когда условие не true, следующее условие catch будет оцениваться вместо этого:

static int a = 7;

static int b = 0;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

Вывод: Общий улов.

При наличии более одного true Exception Filter - будет принят первый:

static int a = 8;

static int b = 4;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

Выход: Catch.

И как вы можете видеть в MSIL, код не переводится в операторы if, но в Filters, и Exceptions не может быть выброшен из областей, отмеченных Filter 1 и Filter 2, но фильтр, выбрасывающий Exception, потерпит неудачу, также последнее значение сравнения, помещенное в стек до того, как команда endfilter определит успех / неудачу фильтра (Catch 1 XOR Catch 2 будет выполняться соответственно):

Exception Filters MSIL

Также, в частности, Guid имеет Guid.TryParse метод.

31
ответ дан Tamir Vered 18 October 2017 в 12:39
поделиться

Ради полноты, начиная с .NET 4.0 код можно переписать так:

Guid.TryParse(queryString["web"], out WebId);

TryParse никогда не генерирует исключения и возвращает false, если формат неправильно, установив WebId на Guid.Empty.


Начиная с C # 7 , вы можете избежать введения переменной в отдельной строке:

Guid.TryParse(queryString["web"], out Guid webId);

Вы также можете создать методы для анализа возвращаемых кортежей, которые недоступны в .NET Framework, начиная с версии 4.6:

(bool success, Guid result) TryParseGuid(string input) =>
    (Guid.TryParse(input, out Guid result), result);

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

WebId = TryParseGuid(queryString["web"]).result;
// or
var tuple = TryParseGuid(queryString["web"]);
WebId = tuple.success ? tuple.result : DefaultWebId;

Следующее бесполезное обновление этого бесполезного ответа происходит, когда деконструкция внешнего параметры реализованы в C # 12.:)

129
ответ дан Athari 18 October 2017 в 12:39
поделиться

Как уже отмечали другие, вы можете иметь оператор if внутри блока catch, чтобы определить, что происходит. C # 6 поддерживает фильтры исключений, поэтому будет работать следующее:

try { … }
catch (Exception e) when (MyFilter(e))
{
    …
}

Затем метод MyFilter может выглядеть примерно так:

private bool MyFilter(Exception e)
{
  return e is ArgumentNullException || e is FormatException;
}

В качестве альтернативы, все это можно сделать inline (правая часть оператора when просто должна быть логическим выражением).

try { … }
catch (Exception e) when (e is ArgumentNullException || e is FormatException)
{
    …
}

Это отличается от использования оператора if внутри блока catch, использование фильтров исключений не будет разматывать стек.

Вы можете загрузить Visual Studio 2015 , чтобы проверить это.

Если вы хотите продолжить использование Visual Studio 2013, вы можете установить следующий пакет nuget:

Install-Package Microsoft.Net.Compilers

На момент написания, это будет включать поддержку C # 6.

Ссылка на этот пакет приведет к тому, что проект будет построен с использованием конкретной версии компиляторов C # и Visual Basic, содержащихся в пакете, в отличие от любой установленной версии системы.

310
ответ дан Joe 18 October 2017 в 12:39
поделиться

Предупрежден и предупрежден: Еще один вид, функциональный стиль.

То, что в ссылке, не отвечает на ваш вопрос напрямую, но тривиально расширить его, чтобы он выглядел следующим образом:

static void Main() 
{ 
    Action body = () => { ...your code... };

    body.Catch<InvalidOperationException>() 
        .Catch<BadCodeException>() 
        .Catch<AnotherException>(ex => { ...handler... })(); 
}

(В основном, предоставляет еще одну пустую перегрузку Catch, которая возвращает сама себя )

Большой вопрос к этому - , почему . Я не думаю, что стоимость перевешивает выигрыш здесь:)

11
ответ дан nawfal 18 October 2017 в 12:39
поделиться

Я хочу предложить кратчайший ответ (еще один функциональный стиль ):

        Catch<FormatException, OverflowException>(() =>
            {
                WebId = new Guid(queryString["web"]);
            },
            exception =>
            {
                WebId = Guid.Empty;
            });

Для этого вам нужно создать несколько перегрузок метода «Catch», аналогично System.Action:

    [DebuggerNonUserCode]
    public static void Catch<TException1, TException2>(Action tryBlock,
        Action<Exception> catchBlock)
    {
        CatchMany(tryBlock, catchBlock, typeof(TException1), typeof(TException2));
    }

    [DebuggerNonUserCode]
    public static void Catch<TException1, TException2, TException3>(Action tryBlock,
        Action<Exception> catchBlock)
    {
        CatchMany(tryBlock, catchBlock, typeof(TException1), typeof(TException2), typeof(TException3));
    }

и так далее, столько, сколько вы хотите. Но вам нужно сделать это один раз, и вы можете использовать его во всех своих проектах (или, если вы создали пакет nuget, мы могли бы использовать его тоже).

И реализация CatchMany:

    [DebuggerNonUserCode]
    public static void CatchMany(Action tryBlock, Action<Exception> catchBlock,
        params Type[] exceptionTypes)
    {
        try
        {
            tryBlock();
        }
        catch (Exception exception)
        {
            if (exceptionTypes.Contains(exception.GetType())) catchBlock(exception);
            else throw;
        }
    }

p.s. Я не ставил нулевые проверки для простоты кода, рассмотрите возможность добавления проверки параметров.

p.s.2 Если вы хотите вернуть значение из catch, необходимо сделать те же методы Catch, но с параметрами Return и Func вместо Action.

0
ответ дан Eugene Gorbovoy 18 October 2017 в 12:39
поделиться

Это вариант ответа Мэтта (я чувствую, что это немного чище) ... используйте метод:

public void TryCatch(...)
{
    try
    {
       // something
       return;
    }
    catch (FormatException) {}
    catch (OverflowException) {}

    WebId = Guid.Empty;
}

Любые другие исключения будут выброшены, и код WebId = Guid.Empty; победит ' быть пораженным. Если вы не хотите, чтобы другие исключения вызывали сбой вашей программы, просто добавьте это ПОСЛЕ двух других зацепок:

...
catch (Exception)
{
     // something, if anything
     return; // only need this if you follow the example I gave and put it all in a method
}
17
ответ дан bsara 18 October 2017 в 12:39
поделиться

РЕДАКТИРОВАТЬ: Я согласен с другими, которые говорят, что с C # 6.0 фильтры исключений теперь являются идеальным способом: catch (Exception ex) when (ex is ... || ex is ... )

За исключением того, что я до сих пор вид ненависти макета с одной длинной строкой и лично выложил бы код следующим образом. Я думаю, что это так же функционально, как и эстетично, так как я считаю, что это улучшает понимание. Некоторые могут не согласиться:

catch (Exception ex) when (
    ex is ...
    || ex is ...
    || ex is ...
)

ОРИГИНАЛ:

Я знаю, что я немного опоздал на вечеринку здесь, но святой дым ...

Если перейти прямо к погоне, этот вид дублирует более ранний ответ, но если вы действительно хотите выполнить общее действие для нескольких типов исключений и сохранить все в чистоте и порядке в рамках одного метода, почему бы не просто использовать лямбда / закрытие / встроенную функцию, чтобы сделать что-то вроде следующего? Я имею в виду, что вполне вероятно, что в итоге вы поймете, что просто хотите сделать это закрытие отдельным методом, который вы можете использовать повсюду. Но тогда это будет очень легко сделать без реального структурного изменения остальной части кода. Правильно?

private void TestMethod ()
{
    Action<Exception> errorHandler = ( ex ) => {
        // write to a log, whatever...
    };

    try
    {
        // try some stuff
    }
    catch ( FormatException  ex ) { errorHandler ( ex ); }
    catch ( OverflowException ex ) { errorHandler ( ex ); }
    catch ( ArgumentNullException ex ) { errorHandler ( ex ); }
}

Я не могу не задаться вопросом ( предупреждение: впереди немного иронии / сарказма), зачем, черт возьми, приложить все эти усилия, чтобы просто заменить следующее:

try
{
    // try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}

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

// sorta sucks, let's be honest...
try
{
    // try some stuff
}
catch( Exception ex )
{
    if (ex is FormatException ||
        ex is OverflowException ||
        ex is ArgumentNullException)
    {
        // write to a log, whatever...
        return;
    }
    throw;
}

Потому что это, конечно, автоматически не более читабельно.

Конечно, я оставил три идентичных экземпляра /* write to a log, whatever... */ return; из первого примера.

1123 Но это моя точка зрения. Вы все слышали о функциях / методах, верно? Шутки в сторону. Напишите общую функцию ErrorHandler и, как ее, вызывайте из каждого блока catch.

Если вы спросите меня, второй пример (с ключевыми словами if и is) значительно менее читабелен и одновременно значительно более подвержен ошибкам на этапе обслуживания вашего проекта.

Фаза обслуживания для тех, кто может быть относительно новичком в программировании, будет составлять 98,7% или более от общего срока службы вашего проекта, и плохое чмо, выполняющее обслуживание, почти наверняка будет кем-то другим, кроме вас. , И есть очень хороший шанс, что они будут тратить 50% своего времени на работу, ругая ваше имя.

И, конечно, FxCop лает на вас, и поэтому вы должны также добавить атрибут в ваш код, который имеет точный zip, связанный с работающей программой, и доступен только для попросите FxCop игнорировать проблему, которая в 99,9% случаев является абсолютно правильной при маркировке. И, извините, я могу ошибаться, но разве этот атрибут «игнорировать» не скомпилирован в ваше приложение?

Не сделает ли тест if в одной строке его более читабельным? Я так не думаю. Я имею в виду, у меня когда-то был другой программист, яростно споривший однажды, что размещение большего количества кода в одной строке заставит его «работать быстрее». Но, конечно, он был совершенно безумным. Попытка объяснить ему (с открытым лицом - что было непросто), как интерпретатор или компилятор разбил бы эту длинную строку на дискретные операторы по одной инструкции на строку - по существу, идентичные результату, если бы он пошел вперед и просто сделал код читабельным вместо того, чтобы пытаться перехитрить компилятор - не оказал на него никакого влияния. Но я отвлекся.

Насколько менее читаемым это становится, когда вы добавляете еще три типа исключений, через месяц или два? (Ответ: становится лот менее читабельным).

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

Просто говорю ...

// super sucks...
catch( Exception ex )
{
    if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
    {
        // write to a log, whatever...
        return;
    }
    throw;
}
479
ответ дан Craig 18 October 2017 в 12:39
поделиться

Поскольку я чувствовал, что эти ответы только коснулись поверхности, я попытался копать немного глубже.

Итак, что мы действительно хотим сделать, это что-то, что не компилируется, скажем:

// Won't compile... damn
public static void Main()
{
    try
    {
        throw new ArgumentOutOfRangeException();
    }
    catch (ArgumentOutOfRangeException)
    catch (IndexOutOfRangeException) 
    {
        // ... handle
    }

Причина, по которой мы этого хотим, заключается в том, что мы не хотим, чтобы обработчик исключений перехватывал то, что мы нужно позже в процессе. Конечно, мы можем поймать исключение и проверить, что делать, если «да», но давайте будем честными, мы этого не хотим. (FxCop, проблемы отладчика, уродливость)

Так почему же этот код не скомпилируется - и как мы можем взломать его таким образом, что он будет?

Если мы посмотрим на код, то, что мы действительно хотели бы сделать, это перезвонить. Однако, согласно MS Partition II, блоки обработчиков исключений IL не будут работать таким образом, что в этом случае имеет смысл, поскольку это подразумевает, что объект «исключения» может иметь разные типы.

Или, чтобы записать это в коде, мы просим компилятор сделать что-то вроде этого (ну, это не совсем правильно, но я думаю, это самая близкая вещь):

// Won't compile... damn
try
{
    throw new ArgumentOutOfRangeException();
}
catch (ArgumentOutOfRangeException e) {
    goto theOtherHandler;
}
catch (IndexOutOfRangeException e) {
theOtherHandler:
    Console.WriteLine("Handle!");
}

Причина то, что это не скомпилируется, совершенно очевидно: какой тип и значение будет иметь объект $ exception (которые здесь хранятся в переменных 'e')? Мы хотим, чтобы компилятор справился с этим, отметив, что общим базовым типом обоих исключений является «Исключение», используйте его для переменной, содержащей оба исключения, а затем обрабатывайте только два захваченных исключения. Способ, которым это реализовано в IL, является «фильтром», который доступен в VB.Net.

Чтобы заставить его работать в C #, нам нужна временная переменная с правильным базовым типом «Exception». Чтобы контролировать поток кода, мы можем добавить несколько веток. Вот что:

    Exception ex;
    try
    {
        throw new ArgumentException(); // for demo purposes; won't be caught.
        goto noCatch;
    }
    catch (ArgumentOutOfRangeException e) {
        ex = e;
    }
    catch (IndexOutOfRangeException e) {
        ex = e;
    }

    Console.WriteLine("Handle the exception 'ex' here :-)");
    // throw ex ?

noCatch:
    Console.WriteLine("We're done with the exception handling.");

Очевидными недостатками этого являются то, что мы не можем правильно перебросить, и, давайте будем честными, это довольно уродливое решение. Уродство можно немного исправить, выполнив удаление ветвей, что делает решение немного лучше:

Exception ex = null;
try
{
    throw new ArgumentException();
}
catch (ArgumentOutOfRangeException e)
{
    ex = e;
}
catch (IndexOutOfRangeException e)
{
    ex = e;
}
if (ex != null)
{
    Console.WriteLine("Handle the exception here :-)");
}

Остается только «перебросить». Чтобы это работало, нам нужно иметь возможность выполнять обработку внутри блока «catch» - и единственный способ выполнить эту работу - перехватывать объект «Exception».

На данный момент, мы можем добавить отдельную функцию, которая обрабатывает различные типы исключений, используя разрешение перегрузки, или обрабатывает исключение. Оба имеют недостатки. Для начала вот способ сделать это с помощью вспомогательной функции:

private static bool Handle(Exception e)
{
    Console.WriteLine("Handle the exception here :-)");
    return true; // false will re-throw;
}

public static void Main()
{
    try
    {
        throw new OutOfMemoryException();
    }
    catch (ArgumentException e)
    {
        if (!Handle(e)) { throw; }
    }
    catch (IndexOutOfRangeException e)
    {
        if (!Handle(e)) { throw; }
    }

    Console.WriteLine("We're done with the exception handling.");

И другое решение - перехватить объект Exception и обработать его соответствующим образом. Наиболее буквальный перевод для этого, основанный на контексте выше, является следующим:

try
{
    throw new ArgumentException();
}
catch (Exception e)
{
    Exception ex = (Exception)(e as ArgumentException) ?? (e as IndexOutOfRangeException);
    if (ex != null)
    {
        Console.WriteLine("Handle the exception here :-)");
        // throw ?
    }
    else 
    {
        throw;
    }
}

Итак, сделаем вывод:

  • Если мы не хотим перебрасывать, мы могли бы рассмотрите возможность обнаружения правильных исключений и временного их хранения.
  • Если обработчик прост, и мы хотим повторно использовать код, лучшим решением, вероятно, будет введение вспомогательной функции.
  • Если мы хотим перебросить, у нас нет другого выбора, кроме как поместить код в обработчик перехвата 'Exception', который сломает FxCop и необработанные исключения вашего отладчика.
7
ответ дан atlaste 18 October 2017 в 12:39
поделиться

Логические разделы существуют для преодоления ограничения MBR (Главная загрузочная запись), которая только разрешает 4 "медосмотра" (IE, не логичный) разделы. Нет никакого различия в операции между логическими и физическими разделами.

возможно лучше использовать логические разделы, поскольку это позволяет создание больше чем 4 разделов в будущем. 1 группа логического раздела занимает одно физическое место раздела, но может содержать партии (не знайте предел) логических разделов.

6
ответ дан jackweirdy 22 October 2019 в 14:05
поделиться

Можно установить Ubuntu на любом разделе. На самом деле я никогда не создаю основные разделы вообще; я создаю один большой расширенный раздел, и все установки установлены в этом расширенном разделе (у меня нет Windows, хотя).

Используя этот метод, Вы не ограничены 4 разделами, и намного легче изменить размер разделов в случае необходимости. Я не знаю ни о какой оборотной стороне к не использованию основных разделов вообще.

2
ответ дан Marty Fried 22 October 2019 в 14:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: