[英]Inconsistent accessibility: return type is less accessible than method in RESTful service
[英]Inconsistent accessibility: return type is less than method
我知道經常會問到inconsistent accessibility
的問題,而我的問題也有所不同,因為我需要將其保密。
讓我給詳細的解釋:我有一個靜態類Line
,以及一個struct LingSegment
的Line
,用戶可以自己定義LineSegment
的Line
,我需要確保有線段之間沒有沖突。
架構如下:
public static class Line {
private struct LineSegment {
public LineSegment(int start, int end) {
Start = start;
End = end;
}
public readonly int Start;
public readonly int End;
}
// User created LineSegment
static public LineSegment Segment1() {
return new LineSegment(1, 2);
}
static public LineSegment Segment2() {
return new LineSegment(3, 6);
}
}
而且,當用戶要訪問其線段時,只能訪問以下內容:
int start = Line.Segment1.Start;
int end = Line.Segment1.End;
我將LineSegment
設為private
的原因是:我只希望用戶通過Line
靜態函數(例如Segment1
, Segment2
創建和訪問LineSegment
。 這樣我就可以使用反射添加一個單元測試,以獲取Line
所有方法,並獲取所有線段的起點和終點,然后判斷線段之間是否存在沖突。
如果LineSegment
是公開的,則用戶僅可以使用new Line.LineSegment(2, 5)
來入侵自己的代碼,而我無法通過單元測試檢測到它。 我不希望他們在Line
之外創建LineSegment
。
但是由於可訪問性不一致,因此在C#中不允許制作LineSegment
。 他們有什么解決方案可以滿足我的要求嗎? 謝謝!
那怎么辦:給他們訪問權限但警告他們...
public static class Line {
public struct LineSegment {
[Obsolete("DO NOT USE THIS DIRECTLY...")]
public LineSegment(int start, int end) {
Start = start;
End = end;
}
public readonly int Start;
public readonly int End;
}
// User created LineSegment
static public LineSegment Segment1() {
return _CreateSegment(1, 2);
}
static public LineSegment Segment2() {
return _CreateSegment(3, 6);
}
static private LineSegment _CreateSegment(int start,int end) {
//we don't want to trigger the warning ...
#pragma warning disable 618
return new LineSegment(3, 6);
#pragma warning restore 618
}
}
在這些情況下,一種經過良好嘗試的模式是定義一個公共接口,並使用一個公共(或內部)構造函數將內部類保持私有。 這樣,您可以防止在同一個項目上工作的其他開發人員(甚至將來您自己)也可以直接調用構造函數,同時仍然可以讓他們訪問類的相關屬性。 因此,首先定義接口:
public interface ILineSegment
{
int Start { get; }
int End { get; }
}
然后是你的課:
public static class Line
{
private struct LineSegment : ILineSegment
{
public int Start { get; }
public int End { get; }
public LineSegment(int start, int end)
{
Start = start;
End = end;
}
}
// User created LineSegment
static public ILineSegment Segment1()
{
return new LineSegment(1, 2);
}
static public ILineSegment Segment2()
{
return new LineSegment(3, 6);
}
請注意,LineSegment1和LineSegment2的返回值已從LineSegment(它是私有的,不能通過公共方法返回)更改為ILineSegment,后者是公共的並且可以返回。
經過比較並征求意見,最后我選擇使用Environment.StackTrace.Contains
來滿足我的要求。
public static class Line {
public struct LineSegment {
public LineSegment(int start, int end) {
if (!Environment.StackTrace.Contains("MyNamespace.Line") || !Environment.StackTrace.Contains("UnitTest")) {
throw new InvalidOperationException("Outside code is not allowed to call its constructor. Please construct your property in this file refering to the example.");
}
Start = start;
End = end;
}
public readonly int Start;
public readonly int End;
}
// User created LineSegment
static public LineSegment Segment1() {
return new LineSegment(1, 2);
}
static public LineSegment Segment2() {
return new LineSegment(3, 6);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.