代码之家  ›  专栏  ›  技术社区  ›  Jason C

C#处理不返回的非void方法的选项

  •  1
  • Jason C  · 技术社区  · 3 年前

    我有一个 this answer 在我的一些法典中,比如:

    private interface IMath<T> {
        internal T Add (T value1, T value2);
        internal T Negate (T value);
    }
    
    private class Math<T> : IMath<T> {
        internal static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
        // !!! My question concerns this portion of code:
        T IMath<T>.Add (T a, T b) { NoSupport(); }
        T IMath<T>.Negate (T a) { NoSupport(); }
        private static void NoSupport () =>
            throw new NotSupportedException($"no math ops for {typeof(T).Name}");
        // !!! End code-of-interest.
    }
    
    private class Math : IMath<int>, IMath<float> {
        internal static Math P = new Math();
        int IMath<int>.Add (int a, int b) { return a + b; }
        int IMath<int>.Negate (int value) { return -value; }
        float IMath<float>.Add (float a, float b) { return a + b; }
        float IMath<float>.Negate (float value) { return -value; }
    }
    

    如果意图是,例如:

    static T Negate <T> (T v) => Math<T>.P.Negate(v);
    
    // elsewhere...
    _ = Negate(3);    // ok (int)
    _ = Negate(3.0f); // ok (float) 
    _ = Negate(3.0);  // throws NotSupportedException (double)
    

    那个 NoSupport()

    但是,它无法编译(C#8),这两个方法中都出现了预期的“not all control path return a value”错误( Add Negate )那就叫它。

    我明白这一点,我也明白为什么它没有编译,这是有道理的。但是,那么,如何在满足编译器要求的同时,实现使代码简单方便的目标呢?

    从我到目前为止所做的研究来看,似乎没有一种方法可以明确说明一个方法不需要 返回 但我想知道是否有办法。。。

    • ... 指定 无支持()
    • ... 将一行代码标记为无法访问(例如,在调用 无支持() )? 或者。。。
    • ... 将方法标记为始终实际返回值(重写编译器的分析)?

    返回一个值,即使编译器看不到它(有选项吗?)。


    1 回复  |  直到 3 年前
        1
  •  2
  •   Jack T. Spades    3 年前

    最简单的解决办法就是 NoSupport() 从空变为空 T .

        T IMath<T>.Add (T a, T b) => NoSupport();
        T IMath<T>.Negate (T a) => NoSupport();
        private static T NoSupport () =>
            throw new NotSupportedException($"no math ops for {typeof(T).Name}");
    

    此外,还可以使用 CallerMemberNameAttribute NotSupport .

        T IMath<T>.Add (T a, T b) => NoSupport(); //will throw "Add not supported"
        T IMath<T>.Negate (T a) => NoSupport();   //will throw "Negate not supported"
        private static T NoSupport ([CallerMemberName] string method = "") =>
            throw new NotSupportedException($"{method} not supported.");