用于处理不 return 的非 void 方法的 C# 选项
C# options for dealing with non-void methods that don't return
我在我的一些代码中实现了 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),并在两种方法(Add
和 Negate
)中出现预期的“并非所有控制路径 return 一个值”错误叫它。
我明白了,我明白为什么它没有编译,这是有道理的。但是,那么,我怎样才能既让代码简单方便,又能满足编译器的要求呢?
从我目前所做的研究来看,似乎没有办法明确指定某个方法不 return,但我我想知道是否有办法......
- ...指定
NoSupport()
总是抛出异常?或者...
- ... 将一行代码标记为不可访问(例如在调用
NoSupport()
之后)?或者...
- ... 将方法标记为始终实际 returning 一个值(覆盖编译器的分析)?
我的主要目标是消除冗余代码(即我对其他方法持开放态度),我的次要目标是了解 C# 用于处理所有路径 do[=43 的方法的特定选项=] return 一个值,即使编译器看不到它(有任何选项吗?)。
我觉得有一种非常直接的方法,而且我现在只见树木不见森林。
最简单的解决方案是将 NoSupport()
从 void 更改为 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.");
我在我的一些代码中实现了 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),并在两种方法(Add
和 Negate
)中出现预期的“并非所有控制路径 return 一个值”错误叫它。
我明白了,我明白为什么它没有编译,这是有道理的。但是,那么,我怎样才能既让代码简单方便,又能满足编译器的要求呢?
从我目前所做的研究来看,似乎没有办法明确指定某个方法不 return,但我我想知道是否有办法......
- ...指定
NoSupport()
总是抛出异常?或者... - ... 将一行代码标记为不可访问(例如在调用
NoSupport()
之后)?或者... - ... 将方法标记为始终实际 returning 一个值(覆盖编译器的分析)?
我的主要目标是消除冗余代码(即我对其他方法持开放态度),我的次要目标是了解 C# 用于处理所有路径 do[=43 的方法的特定选项=] return 一个值,即使编译器看不到它(有任何选项吗?)。
我觉得有一种非常直接的方法,而且我现在只见树木不见森林。
最简单的解决方案是将 NoSupport()
从 void 更改为 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.");