[英]C# errors: member names cannot be the same as their enclosing type and interfaces declare types
[英]Interfaces Cannot Declare Type Issue C#
這個問題更多的是針對良好的設計實踐,而不是異常和堆棧。 我很抱歉一開始並不清楚。
我希望在C#中為我的類提供自己的例外。 在Java中,以下概念是完全合法的,因此如果您有一些堆棧的具體實現,您可以實現一致的錯誤處理(或任何其他類型的類)
public interface IStack
{
bool IsEmpty();
int Pop();
void Push(int element);
int Size { get; set; }
int Top();
public class EmptyException : Exception
{
}
public class SomeOtherClass
{
}
}
當然,在C#中我得到一個錯誤,說“接口不能聲明類型”
確保只實現我的接口的具體類可以訪問EmptyException等的最佳方法是什么?
謝謝
您不能在接口或枚舉中聲明嵌套的類,接口,結構或枚舉聲明。
嵌套接口,枚舉,結構和類聲明僅允許在struct或class中。
在同一名稱空間中聲明一個類。
[Serializable]
public class StackEmptyException :
InvalidOperationException
{
public StackEmptyException() :
base("Cannot pop an item from an empty stack")
{
}
public StackEmptyException(string message) :
base(message)
{
}
/// <summary>Used for serialization. Never forget it!</summary>
protected StackEmptyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) :
base(info, context)
{
}
}
在C#中,將每個異常類命名為XXXException是一個很好的約定。
由於從空堆棧彈出項目是無效的操作,因此我將使用InvalidOperationException作為基本異常類型。
您還可以使用幾種基類型,例如ArgumentException,ArgumentNullException,InvalidOperationException,ApplicationException。 我建議您至少使用簡單的異常,而不是使用簡單的異常,因此人們可以在catch中更好地過濾異常。
如果可以的話,首選使用已經在框架中聲明的異常類型,有很多並且通常它們已經足夠了,對於您的示例,我將直接使用InvalidOperationException而不編寫新的異常。
我還建議你使它可序列化(添加[Serializable]屬性並復制序列化構造函數)或者將來人們會責怪你“為什么這個人沒有將他的異常序列化,為什么!”。
java和C#關於異常的一個重要區別是,在C#中,每個方法都可以拋出異常,比如C ++。 您不必(也不能)指定方法可以拋出的異常。 但是你可以添加評論......
/// <summary>Pop an item from the stack.</summary>
/// <returns>The element removed from the stack.</returns>
/// <exception cref="System.InvalidOperationException">Throws InvalidOperationException if stack is empty.</exception>
public object Pop() { ... }
僅使代碼引發異常的方法是將主構造函數聲明為internal。 在C#中,內部成員僅在聲明它們的程序集中可見。 因此,如果您正在編寫庫,則只需添加內部關鍵字即可。 如果您仍希望保持序列化,則無法密封該類,但沒有人能夠在您的庫外調用您的構造函數。
[Serializable]
public class StackEmptyException :
InvalidOperationException
{
// This constructor is internal, it means, only the assembly that contains this exception can throw it.
// In C# there is not the "friend" keyword like in C++ so we can just use internal.
internal StackEmptyException() :
base("Cannot pop an item from an empty stack")
{
}
/// <summary>Used for serialization. Never forget it!</summary>
protected StackEmptyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) :
base(info, context)
{
}
}
然而,沒有辦法在界面內聲明“受保護”的東西,所以你的問題不能得到肯定的答案。 接口中的方法,事件和屬性都是公共的。
您可以使用抽象類,但當然,在C#(如java)中,您沒有多重繼承,因此可能對您沒用。 例外情況應該全部是公開的,或者沒有人可以在你的課堂之外發現你的例外,這是一個糟糕的設計!
可能你試圖強迫語言從設計的角度來執行一些不太好的東西。
例外必須是公開的。 .NET中的異常不是接口契約的一部分,只有屬性方法和事件才是接口契約的一部分。
也許我在你的設計中遺漏了一些東西,但你不需要做任何特殊的事情來確保一個類“可以”拋出異常。 任何類都可以隨時拋出它想要的任何異常。 唯一的要求是異常類是可見的。
確保異常與您的界面在同一個程序集和相同的命名空間中,你會沒事的。
public interface IStack
{
bool IsEmpty();
int Pop();
void Push(int element);
int Size { get; set; }
int Top();
}
public class Empty : Exception
{
}
只要實現接口的類在范圍內具有異常,它就可以拋出它。 我無法弄清楚你要在這里描述什么,你必須幫忙。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.