接口无法声明类型问题C#

这个问题更多的是针对良好的设计实践,而不是exception和堆栈。 我很抱歉一开始并不清楚。

我想在C#中为我的类创建自己的exception。 在Java中,以下概念是完全合法的,因此如果您有一些堆栈的具体实现,您可以实现一致的error handling(或任何其他类型的类)

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) { } /// Used for serialization. Never forget it! protected StackEmptyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } 

在C#中,将每个exception类命名为XXXException是一个很好的约定。

由于从空堆栈弹出项目是无效的操作,因此我将使用InvalidOperationException作为基本exception类型。

您还可以使用几种基类型,例如ArgumentException,ArgumentNullException,InvalidOperationException,ApplicationException。 我建议您至少使用ApplicationException,而不是使用简单的Exception,因此人们可以更好地过滤您的exception。

如果可以的话,首选使用已经在框架中声明的exception类型,有很多并且通常它们已经足够了,对于您的示例,我将直接使用InvalidOperationException而不编写新的exception。

我还建议你使它可序列化(添加[Serializable]属性并复制序列化构造函数)或者将来人们会责怪你“为什么这个人没有将他的exception序列化,为什么!”。

java和C#关于exception的一个重要区别是,在C#中,每个方法都可以抛出exception,比如C ++。 您不必(也不能)指定方法可以抛出的exception。 但是你可以添加评论……

  /// Pop an item from the stack. /// The element removed from the stack. /// Throws InvalidOperationException if stack is empty. public object Pop() { ... } 

只使代码引发exception的一种方法是将主构造函数声明为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") { } /// Used for serialization. Never forget it! protected StackEmptyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } 

然而,没有办法在界面内声明“受保护”的东西,所以你的问题不能得到肯定的答案。 接口中的方法,事件和属性都是公共的。

您可以使用抽象类,但当然,在C#(如java)中,您没有多重inheritance,因此可能对您没用。 例外情况应该是全部公开的,或者没有人可以在你的课外捕捉你的例外,这是一个糟糕的设计!

可能你试图强迫语言从设计的角度来执行一些不太好的东西。

例外必须是公开的。 .NET中的exception不是接口契约的一部分,只有属性方法和事件才是接口契约的一部分。

也许我在你的设计中遗漏了一些东西,但你不需要做任何特殊的事情来确保一个类“可以”抛出exception。 任何类都可以随时抛出它想要的任何exception。 唯一的要求是exception类是可见的。

确保exception与您的界面在同一个程序集和相同的命名空间中,你会没事的。

 public interface IStack { bool IsEmpty(); int Pop(); void Push(int element); int Size { get; set; } int Top(); } public class Empty : Exception { } 

只要实现接口的类在范围内具有exception,它就可以抛出它。 我无法弄清楚你要在这里描述什么,你必须帮忙。