Почему делают “Не, все пути выполнения кода возвращают значение” с оператором переключения и перечислением?

Решает ли это вашу проблему - ссылка на соответствующую ячейку в столбце C? OFFSET обеспечивает относительную ссылку, в этом случае посмотрите 3 столбца слева от F.

Sub Test1()

Dim rngnumbers As Range, rngnames As Range, MultipleRange As Range, numb As Range

Set rngnumbers = Sheet2.Range("F2:F999")
Set rngnames = Sheet2.Range("C2:C999")
Set MultipleRange = Union(rngnumbers, rngnames)

For Each numb In rngnumbers
    If numb.Value >= 100 Then
        If numb.Offset(, -3) = "John" Or numb.Offset(, -3) = "Tom" Then
            Sheet1.Range("I999").End(xlUp).Offset(1, 0).Value = numb.Value
        End If
    End If
Next numb

End Sub

Вы рассматривали SUMIFS вместо этого?

27
задан Matthijs Wessels 21 September 2012 в 15:51
поделиться

5 ответов

Ничего не скажешь, что значение myEnum будет одним из этих значений.

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

int x = Method((MyEnum) 127);

Что бы вы хотели, чтобы это делало? Если вы хотите, чтобы оно генерировало исключение, вы можете сделать это в случае по умолчанию:

switch (myEnum)
{
    case MyEnum.Value1: return 1;
    case MyEnum.Value2: return 2;
    case MyEnum.Value3: return 3;
    default: throw new ArgumentOutOfRangeException();
}

В качестве альтернативы вы можете использовать Enum.IsDefined заранее, если вы хотите сделать какую-то другую работу до оператора switch. Это имеет недостаток в боксе ... Есть несколько способов обойти это, но они, как правило, больше работы ...

Пример:

public int Method(MyEnum myEnum)
{
    if (!IsDefined(typeof(MyEnum), myEnum)
    {
        throw new ArgumentOutOfRangeException(...);
    }
    // Adjust as necessary, e.g. by adding 1 or whatever
    return (int) myEnum; 
}

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

38
ответ дан Jon Skeet 28 November 2019 в 05:22
поделиться

Если вы измените значения в вашем перечислении (добавив четвертое), ваш код сломается. Вы должны добавить default: case к вашему оператору switch.

Конечно, другой способ достичь этого - определить целочисленные значения в вашем перечислении ...

public enum MyEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

, а затем приведите свой enum как int в коде. Вместо int myInt = Method(myEnumValue); вы можете использовать int myInt = (int)myEnum

0
ответ дан ZombieSheep 28 November 2019 в 05:22
поделиться

Это должно быть либо:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
        default: return 0;
    }
}

или:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
    }

    return 0;
}
-1
ответ дан herzmeister 28 November 2019 в 05:22
поделиться
MyEnum blah = 0;

Значение по умолчанию всегда 0 и неявно конвертируемо, даже если вы не имеете один с 0 значениями.

0
ответ дан 28 November 2019 в 05:22
поделиться

Проблема заключается в том, что невозможно получить ссылку на нестатические методы через экземпляр MyType. [Member]. Их можно увидеть только через ссылку на экземпляр типа. Кроме того, невозможно построить метод расширения поверх объявления типа, только на экземпляре типа, т.е. сам метод расширения должен быть определен с помощью экземпляра типа (этот T x).

Однако можно определить выражение так, чтобы получить ссылку на статические члены: ((MyType x) = > MyType.Property)

Можно сделать что-то похожее на последовательность displayName = ((MyType x) = > x.Property) .GetDisplayName (); Первая проблема - гарантировать, что компилятор рассматривает ваше (x = > x.Property) как Выражение, а не действие/func и т.д.... Для этого может потребоваться следующее:

string displayName = ((Expression<Func<PropertyType>>)((MyType x) => x.Property).GetDisplayName();

Метод расширения должен быть определен следующим образом:

public static string GetDisplayName<T>(this Expression<Func<T>> expression)

Также может потребоваться определить метод расширения поверх Выражение < Действие > > и Выражение < Действие < T > > , если члены также являются методами.

Можно создать точку после выражения - здесь будет находиться метод Compile.

Добавлено:

Я думаю, что статический вызов метода расширения в тех случаях, когда отсутствует экземпляр типа, который требуется выполнить «рефлексия» для определения имени Members будет самым чистым синтаксисом - таким образом, можно использовать метод расширения при использовании экземпляра типа и вернуться к статическому определению вызова = > MyExtensionClass.GetDisplayName(TypeOfX x = > TypeOfX.StaticMember OR x.Property/Member) , если экземпляр отсутствует

-121--4482041-

Я думаю, что во многих языках этот подход невозможен, так как они просто не имеют понятия ординалов, которые могут быть составлены из числа с некоторыми буквами в качестве расширения. Для «1-го», т.е. в немецком языке можно написать только «1». или «erster »/« erste »/« erstes» в зависимости от рода того, что вы нумеруете.

-121--5044786-

Перечисления не ограничиваются значениями, которые они представляют. Вы можете назначить это:

MyEnum v = (MyEnum)1000;

И не было бы никаких проблем. Добавьте к коммутатору значение по умолчанию и обработайте все возможные ситуации.

5
ответ дан 28 November 2019 в 05:22
поделиться
Другие вопросы по тегам:

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