C# 接口的非公共成员

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 08:59:08  来源:igfitidea点击:

Non Public Members for C# Interfaces

提问by jfs

In C#, when you implement an interface, all members are implicitly public. Wouldn't it be better if we could specify the accessibility modifier (protected, internal, except privateof course), or should we just use an abstract class instead?

在 C# 中,当您实现一个接口时,所有成员都是隐式公开的。如果我们可以指定可访问性修饰符(protected, internalprivate当然除外),或者我们应该只使用抽象类,不是更好吗?

回答by Ishmaeel

Would not make sense. An Interface is a contract with the publicthat you support those methods and properties. Stick with abstract classes.

没有意义。接口是与您支持这些方法和属性的公众的契约。坚持使用抽象类。

回答by Jon Limjap

Interfaces do not have access modifiers in their methods, leaving them open to whichever access modifier is appropriate. This has a purpose: it allows other types to infer what methods and properties are available for an object following an interface. Giving them protected/internal accessors defeats the purpose of an interface.

接口在它们的方法中没有访问修饰符,让它们对任何合适的访问修饰符开放。这有一个目的:它允许其他类型推断接口后面的对象可以使用哪些方法和属性。为它们提供受保护的/内部访问器违背了接口的目的。

If you are adamant that you need to provide an access modifier for a method, either leave it out of the interface, or as you said, use an abstract class.

如果您坚持需要为方法提供访问修饰符,请将其保留在接口之外,或者如您所说,使用抽象类。

回答by John Topley

I'm familiar with Java rather than C#, but why an earth would you want a private member within an interface? It couldn't have any implementation and would be invisible to implementing classes, so would be useless. Interfaces exist to specify behaviour. If you need default behaviour than use an abstract class.

我熟悉 Java 而不是 C#,但是为什么您想要接口中的私有成员?它不能有任何实现,并且对于实现类来说是不可见的,所以将是无用的。存在用于指定行为的接口。如果您需要默认行为而不是使用抽象类。

回答by Mark Cidade

If an interface is internal, all its members will be internal to the assembly. If a nested interface is protected, only the subclasses of the outer class could access that interface.

如果接口是内部接口,则其所有成员都将位于程序集内部。如果嵌套接口受保护,则只有外部类的子类可以访问该接口。

Internal members for an interface outside of its declaring assembly would be pointless, as would protected members for an interface outside of its declaring outer class.

其声明程序集之外的接口的内部成员将毫无意义,其声明外部类之外的接口的受保护成员也是如此。

The point of an interface is to describe a contractbetween a implementing type and users of the interface. Outside callers aren't going to care and shouldn't haveto care about implementation, which is what internal and protected members are for.

接口的重点是描述实现类型和接口用户之间的契约。外部用户不会去关心,不应该关心的实现,这是内部和保护成员是。

For protected members that are called by a base class, abstract classes are the way to go for specifying a contract between base classes and classes that inherit from them. But in this case, implementation details are usually very relevant, unless it's a degenerate pure abstract class (where allmembers are abstract) in which case protected members are useless. In that case, go with an interface and save the single base class for implementing types to choose.

对于由基类调用的受保护成员,抽象类是在基类和从它们继承的类之间指定契约的方法。但在这种情况下,实现细节通常非常相关,除非它是一个退化的纯抽象类(其中所有成员都是抽象的),在这种情况下受保护的成员是无用的。在这种情况下,使用接口并保存单个基类以供选择的实现类型。

回答by samjudson

You can hide the implementation of an interface by explicitly stating the interface name before the method name:

您可以通过在方法名称之前显式声明接口名称来隐藏接口的实现:

public interface IInterface {
    public void Method();
}

public class A : IInterface {
    public void IInterface.Method() {
        // Do something
    }
}

public class Program {
    public static void Main() {
        A o = new A();
        o.Method(); // Will not compile
        ((IInterface)o).Method(); // Will compile
    }
}

回答by Keith

An interface is a contract that all implementing classes adhere to. This means that they must adhere to all of it or none of it.

接口是所有实现类都遵守的契约。这意味着他们必须全部遵守或完全不遵守。

If the interface is public then every part of that contact has to be public, otherwise it would mean one to friend/internal classes and a different thing to everything else.

如果接口是公开的,那么该联系的每一部分都必须是公开的,否则它对朋友/内部类来说意味着一个,而对其他一切都意味着不同的东西。

Either use an abstract base class or (if possible and practical) an internal extension method on the interface.

在接口上使用抽象基类或(如果可能且实用)内部扩展方法

回答by Keith

You can hide almost all of the code implemented by interfaces to external assemblies.

您可以隐藏几乎所有由外部程序集接口实现的代码。

interface IVehicle
{
    void Drive();
    void Steer();
    void UseHook();
}
abstract class Vehicle  // :IVehicle  // Try it and see!
{
    /// <summary>
    /// Consuming classes are not required to implement this method.
    /// </summary>
    protected virtual void Hook()
    {
        return;
    }
}
class Car : Vehicle, IVehicle
{
    protected override void Hook()  // you must use keyword "override"
    {
        Console.WriteLine(" Car.Hook(): Uses abstracted method.");
    }
    #region IVehicle Members

    public void Drive()
    {
        Console.WriteLine(" Car.Drive(): Uses a tires and a motor.");
    }

    public void Steer()
    {
        Console.WriteLine(" Car.Steer(): Uses a steering wheel.");
    }
    /// <summary>
    /// This code is duplicated in implementing classes.  Hmm.
    /// </summary>
    void IVehicle.UseHook()
    {
        this.Hook();
    }

    #endregion
}
class Airplane : Vehicle, IVehicle
{
    protected override void Hook()  // you must use keyword "override"
    {
        Console.WriteLine(" Airplane.Hook(): Uses abstracted method.");
    }
    #region IVehicle Members

    public void Drive()
    {
        Console.WriteLine(" Airplane.Drive(): Uses wings and a motor.");
    }

    public void Steer()
    {
        Console.WriteLine(" Airplane.Steer(): Uses a control stick.");
    }
    /// <summary>
    /// This code is duplicated in implementing classes.  Hmm.
    /// </summary>
    void IVehicle.UseHook()
    {
        this.Hook();
    }

    #endregion
}

This will test the code.

这将测试代码。

class Program
{
    static void Main(string[] args)
    {
        Car car = new Car();
        IVehicle contract = (IVehicle)car;
        UseContract(contract);  // This line is identical...
        Airplane airplane = new Airplane();
        contract = (IVehicle)airplane;
        UseContract(contract);  // ...to the line above!
    }

    private static void UseContract(IVehicle contract)
    {
        // Try typing these 3 lines yourself, watch IDE behavior.
        contract.Drive();
        contract.Steer();
        contract.UseHook();
        Console.WriteLine("Press any key to continue...");
        Console.ReadLine();
    }
}

回答by nawfal

All the answers here more or less say that's how interfaces are meant to be, they are universal public specifications.

这里的所有答案或多或少都表明接口应该是这样的,它们是通用的公共规范。

This being the most discussed thread, let me post two excellent answers I found on SO when this question surfaced my mind.

这是讨论最多的主题,当这个问题浮现在我的脑海时,让我发布我在 SO 上找到的两个很好的答案。

This answer gives an exampleof how it can be nonsensical to have non uniform access specifiers for interface members in derived classes. Code always better than technical descriptions.

这个答案给出了一个例子,说明为派生类中的接口成员使用非统一访问说明符是多么荒谬。代码总是比技术描述更好。

To me the most damning thing about forced public interface members are that the interface itself can be internal to an assembly but the members it exposes have to be public. Jon Skeet explains here that's by design sadly.

对我来说,强制公开接口成员最糟糕的事情是接口本身可以在程序集内部,但它公开的成员必须是公开的。乔恩·斯基特 (Jon Skeet) 可悲地解释说,这是设计使然

That raises the question why weren't interfaces designed to have non-public definitions for members. That can make the contract flexible. This is pretty useful when writing assemblies where you dont want specific members of classes to be exposed to outside the assembly. I do not know why.

这就提出了一个问题,为什么接口的设计不是为成员提供非公开定义。这可以使合同具有灵活性。在编写不希望类的特定成员暴露给程序集外部的程序集时,这非常有用。我不知道为什么。

回答by Ini

In my opintion this violates encapsulation. I have to implement a methos as public then I implement an interface. I see no reason to force public in a class that impletements the interface. (c#)

在我看来,这违反了封装。我必须实现一个公开的方法,然后我实现一个接口。我认为没有理由在实现接口的类中强制公开。(C#)