programing

C#에서 공개, 비공개, 보호 및 액세스 수식어가 없는 것의 차이점은 무엇입니까?

i4 2023. 5. 1. 19:57
반응형

C#에서 공개, 비공개, 보호 및 액세스 수식어가 없는 것의 차이점은 무엇입니까?

대학 시절 내내 사용해 온 것은public그리고 사이의 차이점을 알고 싶습니다.public,private,그리고.protected?

또한무이가 입니까?static아무것도 가지지 않는 것과 반대로 하십니까?

액세스 한정자

learn.microsoft.com 에서:

public

유형 또는 멤버는 동일한 어셈블리 또는 이를 참조하는 다른 어셈블리의 다른 코드를 통해 액세스할 수 있습니다.

private

형식 또는 구성원은 동일한 클래스 또는 구조체의 코드로만 액세스할 수 있습니다.

protected

형식 또는 구성원은 동일한 클래스나 구조체 또는 파생 클래스의 코드로만 액세스할 수 있습니다.

private protected (C# 7.2에 추가됨)

형식 또는 멤버는 동일한 클래스 또는 구조체의 코드로만 액세스할 수 있으며, 다른 어셈블리에서는 액세스할 수 없습니다.

internal

유형 또는 멤버는 동일한 어셈블리의 모든 코드로 액세스할 수 있지만 다른 어셈블리에서는 액세스할 수 없습니다.

protected internal

형식 또는 멤버는 동일한 어셈블리의 모든 코드 또는 다른 어셈블리의 파생 클래스를 통해 액세스할 수 있습니다.

액세스 한정자가 설정되지 않은 경우 기본 액세스 한정자가 사용됩니다.따라서 설정되지 않은 경우에도 항상 어떤 형태의 액세스 수정자가 존재합니다.

static

클래스의 정적 한정자는 클래스를 인스턴스화할 수 없으며 모든 구성원이 정적임을 의미합니다.정적 구성원은 작성된 엔클로저 유형의 인스턴스 수에 관계없이 하나의 버전을 가집니다.

정적 클래스는 기본적으로 정적 클래스가 아닌 클래스와 동일하지만 한 가지 차이점이 있습니다. 정적 클래스는 외부적으로 인스턴스화될 수 없습니다.즉, 새 키워드를 사용하여 클래스 유형의 변수를 만들 수 없습니다.인스턴스 변수가 없으므로 클래스 이름 자체를 사용하여 정적 클래스의 멤버에 액세스합니다.

그러나 정적 생성자와 같은 것이 있습니다.모든 클래스는 정적 클래스를 포함하여 이러한 클래스 중 하나를 가질 수 있습니다.클래스를 직접 호출할 수 없으며 클래스 자체의 형식 매개 변수를 제외한 매개 변수를 가질 수 없습니다.정적 생성자는 첫 번째 인스턴스가 생성되거나 정적 멤버가 참조되기 전에 클래스를 초기화하기 위해 자동으로 호출됩니다.다음과 같이 표시됩니다.

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }
    
    public static string Bar { get; set; }
}

정적 클래스는 종종 서비스로 사용되며 다음과 같이 사용할 수 있습니다.

MyStaticClass.ServiceMethod(...);

그래픽 개요(간단히 요약)

가시성

사실, 그것보다 조금 더 복잡합니다.
이제(C# 7.2 기준) 개인 보호 기능도 있습니다. 파생 클래스가 동일한 어셈블리에 있는지 여부가 중요합니다.

따라서 개요를 확장해야 합니다.

가시성 확장

주제에 대한 C#-dotnet-docs도 참조하십시오.

정적 클래스는 봉인되어 있으므로 개체를 제외하고는 상속할 수 없으므로 보호되는 키워드는 정적 클래스에서 유효하지 않습니다.



앞에 액세스 한정자를 지정하지 않은 경우 기본값은 다음을 참조하십시오.
C# 클래스 및 멤버(필드, 메서드 등)에 대한 기본 가시성?

비내포

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

중첩:

nested enum      public
nested interface public
nested class     private
nested struct    private

또한 클래스를 상속할 수 없도록 만드는 sealed-keyword도 있습니다.
.수 있으므로 과 같이 작성합니다.NET, 키워드가 다를 수 있습니다. 따라서 여기에 부정행위 시트가 있습니다.

VB 대 CS 등가물

Public(공용) - 클래스를 볼 수 있는 경우 메서드를 볼 수 있습니다.

개인 - 클래스에 속한 경우 메서드를 볼 수 있지만 그렇지 않은 경우에는 볼 수 없습니다.

보호됨 - 개인과 동일하며 모든 하위 항목에서도 메서드를 볼 수 있습니다.

정적(클래스) - "클래스"와 "오브젝트"의 구별을 기억하십니까? 모든 것을 잊어버리십시오."정적"도 마찬가지입니다.클래스는 클래스의 유일한 인스턴스입니다.

정적(메소드) - 이 메서드를 사용할 때마다 이 메서드는 해당 메서드가 속한 클래스의 실제 인스턴스와 독립적으로 참조 프레임을 가집니다.

답변의 멋진 다이어그램을 다시 게시합니다.

다음은 Venn 다이어그램의 액세스 한정자이며, 더 많은 제한자에서 더 많은 비규칙(Promiscuous) 액세스 수식자입니다.

private:
여기에 이미지 설명 입력

private protected- C# 7.2에 추가됨
여기에 이미지 설명 입력

internal:
여기에 이미지 설명 입력

protected:
여기에 이미지 설명 입력

protected internal:
여기에 이미지 설명 입력

public:
여기에 이미지 설명 입력

그러나 현재 액세스 수정자(C# 7.2)의 또 다른 시각적 접근법.스키마가 그것을 더 쉽게 기억하는 데 도움이 되기를 바랍니다.
(대화형 보기를 위해 이미지를 클릭합니다.)

대화형 액세스 수정자 svg

외부 내부

두 단어로 된 액세스 수정자를 기억하는 데 어려움을 겪는 경우 외부를 기억하십시오.

  • 개인 보호됨: 개인 외부(동일 어셈블리) 내부(동일 어셈블리) 보호됨
  • 보호된 내부: 외부(동일한 어셈블리) 내부(동일한 어셈블리)에서 내부(동일한 어셈블리)

여기에 이미지 설명 입력

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}

아무것도 아닌 질문과 관련하여

  • 네임스페이스 유형은 기본적으로 내부입니다.
  • 중첩된 유형을 포함한 모든 유형 구성원은 기본적으로 비공개입니다.

공용 - 어디서나 누구나 액세스할 수 있습니다.
개인 - 자신이 속한 클래스 내에서만 액세스할 수 있습니다.
protected - 클래스 내 또는 클래스에서 상속되는 모든 개체에서만 액세스할 수 있습니다.

VB를 제외하고는 null과 같은 것은 없습니다.
정적은 해당 클래스의 모든 인스턴스에 대해 해당 개체의 인스턴스, 메서드가 하나씩 있음을 의미합니다.

음.

다음을 참조:수정자에 액세스합니다.

간단히 말해서,

Public(공용)은 메서드 또는 유형을 다른 유형/클래스에서 완전히 볼 수 있도록 합니다.

Private는 Private 메서드/변수를 포함하는 유형만 Private 메서드/변수에 액세스할 수 있습니다. 중첩된 클래스는 Private 메서드/변수를 포함하는 클래스에도 액세스할 수 있습니다.

보호됨은 파생 클래스가 보호된 메서드에도 액세스할 수 있다는 점을 제외하고 개인과 유사합니다.

"Nothing"은 VB입니다.NET은 null에 해당합니다."아무것도"가 "액세스 수정자가 없음"을 의미하는 경우에도, 매우 대략적인 경험칙(C#에서 확실히)은 액세스 수정자를 명시적으로 지정하지 않으면 메서드/변수 선언이 일반적으로 가능한 한 제한됩니다.

public class MyClass
{
    string s = "";
}

는 사실상 다음과 같습니다.

public class MyClass
{
    private string s = "";
}

연결된 MSDN 문서는 액세스 수정자가 명시적으로 지정되지 않은 경우 전체 설명을 제공합니다.

음...

정적은 클래스의 인스턴스 없이 해당 함수에 액세스할 수 있음을 의미합니다.

클래스 정의에서 직접 액세스할 수 있습니다.

Private 상태는 동일한 클래스의 개체만 변수에 액세스할 수 있음을 나타냅니다.보호 상태는 클래스의 하위 항목도 포함하도록 액세스를 확장합니다.

"위의 표에서 우리는 사적인 것과 보호받는 것의 차이를 볼 수 있습니다"저는 둘 다 동일하다고 생각합니다 ..그래서 그 두 개의 분리된 명령이 필요한 것은 무엇입니까."

자세한 내용은 MSDN 링크를 확인하십시오.

  • public클래스 자체를 포함하여 모든 어셈블리의 모든 클래스에서 액세스할 수 있음을 의미합니다.
  • protected internal클래스 자체(클래스 정의에서)에 의해 액세스할 수 있으며 현재 어셈블리의 모든 클래스에 의해 액세스할 수 있지만 어셈블리 외부에서는 클래스를 상속하는 클래스 또는 클래스 자체(부분 클래스인 경우)에만 액세스할 수 있습니다. 기본적으로 의미는 기본적으로internal 및 블리내및부어셈및.protected의회 밖에
  • protected 수 수 해당 에 있을 수 있습니다.
  • internal클래스 자체 또는 어셈블리의 모든 클래스가 액세스할 수 있지만 클래스 자체(즉, 부분 클래스)가 아닌 한 어셈블리 외부에서는 액세스할 수 없음을 의미합니다.
  • private protected클래스 자체에서만 액세스할 수 있거나 클래스가 현재 어셈블리에 있는 경우에만 클래스를 상속하는 클래스에서 액세스할 수 있습니다.어셈블리 외부에서는 클래스 자체(즉, 부분 클래스)로만 액세스할 수 있습니다. 기본적으로 다음과 같이 구성됩니다.internal그리고.protected또는다말표로면자하현은그, 것른은▁or▁it.private에서 그리고 회의밖그리고서에고▁outside그리.protected집회의 내부에
  • private 수 입니다.
  • 액세스 한정자 없음:C#의 모든 항목에 대한 기본 액세스는 "해당 구성원에 대해 선언할 수 있는 가장 제한된 액세스"입니다. 즉,private 및 " " " "/" "/" "/" "" " " " " "의 경우"internal비흡연자 수업의 경우.

것을 하며, 인 위트액 '은세됨스유 ' 래스형 ' 클의개 ' 체스를 ' 해하의 ' 미며통 ' 세텍것 ' 을는되 ' 스서액에의 ' 됩클가니미다래 ', 스 자체의메서드인내적암시서에'ed▁means▁be▁in▁the니됩다,클래스▁accessed가,▁via▁aaccess며은▁type의미▁'▁of위▁of▁itself▁class▁implicit자▁will▁class액▁object▁the체▁withinthis개체 또는 메소드는 현재 클래스 유형의 명시적 개체를 인스턴스화하고 해당 개체를 통해 액세스합니다.둘 다 클래스 자체에서 액세스하는 것으로 간주되므로 액세스 규칙은 동일합니다.이것은 정적 메서드에서 수행되는 액세스에도 적용되며, 액세스하는 정적 멤버/메소드인 경우에는 클래스 범위가 아닌 개체를 사용하여 수행됩니다.정적 클래스의 멤버/메소드를 명시적으로 만들어야 합니다.static컴파일이 되지 않습니다.

는 첩되지않클래다는같음수있다습니을과중은이 될 수 .public또는internal그리고 지금은internal는 모든 , 인 경우 일 필요가 없습니다.중첩된 클래스는 모든 액세스 유형일 수 있으며, 상위 클래스가 정적인 경우 정적일 필요가 없고 구성원도 정적일 필요가 없습니다.안 안internalclass는 인스턴스화되거나 현재 어셈블리에서 해당 정적 멤버에만 액세스할 수 있음을 의미합니다.

멤버는 " " "/" "/" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""internal또는private중첩 클래스 - 수행 중인 현재 액세스에 필요한 수준보다 낮은 액세스 지정자(수행 중인 액세스의 정규화된 이름)만 액세스를 금지합니다.

C C#입니다.public으로 또는 상속할 수 C이 합니다. C++ 인개와달리는또있이로는으속적, 스에서상속는되클클래스에래서다상속니액되변모 는클든래합스의경세스를는호보적 으로할상수▁unlike+와▁which개▁that▁c,▁classes+▁the변액▁privately경합를니다+,▁can스ly세▁which클클모는▁changes의래스래는상스▁protected▁that▁or상에▁inherit속되인,든서서이▁class클래스에서 개인적으로/보호적으로 상속되는 클래스와 개인적으로/보호적으로 상속되는 클래스에서 상속되는 클래스의 유형의 개체/클래스 범위를 통한 액세스 등.모든 액세스 한정자가 다음보다 덜 제한적이 되도록 액세스가 변경되었습니다.private또는protectedprivate그리고.protected각각 다음과 같다.

조심해야 해!수업의 접근성을 확인합니다.공용 및 보호된 클래스 및 메서드는 기본적으로 모든 사용자가 액세스할 수 있습니다.

또한 Microsoft는 액세스 수식자(공개, 보호 등)를 표시하는 데 있어 그다지 명시적이지 않습니다.키워드)를 클릭합니다.따라서 수업이 구현 내부로 가는 문이기 때문에 잘 관리하고 수업의 접근성에 대해 생각해 보십시오.

이러한 접근 한정자는 구성원이 표시되는 위치를 지정합니다.당신은 아마 이것을 읽어봐야 할 것입니다.이아인이 준 링크를 가져가세요.MH를 시작점으로 합니다.

정적 멤버는 인스턴스당 하나가 아니라 클래스당 하나입니다.

좋은 OOP 디자인과 관련이 있다고 생각합니다.라이브러리 개발자인 경우 라이브러리의 내부 작동을 숨기려고 합니다.이렇게 하면 나중에 라이브러리 내부 작업을 수정할 수 있습니다.구성원과 도우미 메소드를 비공개로 설정하고 인터페이스 메소드만 공개합니다.덮어써야 하는 메서드는 보호되어야 합니다.

C#에는 총 6개의 액세스 한정자가 있습니다.

비공개:이 접근성으로 선언된 멤버는 포함 유형 내에서 볼 수 있으며, 파생된 유형, 동일한 어셈블리의 다른 유형 또는 포함 어셈블리 외부의 유형에는 표시되지 않습니다. 즉, 액세스가 포함 유형으로만 제한됩니다.

보호됨:이 접근성으로 선언된 멤버는 포함 어셈블리 내의 포함 형식에서 파생된 형식 내에서 볼 수 있으며, 포함 어셈블리 외부의 포함 형식에서 파생된 형식(즉, 액세스가 포함 형식의 파생 형식으로 제한됨) 내에서 볼 수 있습니다.

내부:이 접근성으로 선언된 구성원은 이 구성원을 포함하는 어셈블리 내에서 볼 수 있으며, 포함하는 어셈블리 외부에서는 볼 수 없습니다. 즉, 액세스가 포함하는 어셈블리로만 제한됩니다.

내부 보호:이 접근성으로 선언된 부재는 포함 어셈블리 내부 또는 외부의 포함 형식에서 파생된 형식 내에서 볼 수 있으며, 포함 어셈블리 내의 모든 형식에서도 볼 수 있습니다. 즉, 액세스가 포함 어셈블리 또는 파생 형식으로 제한됩니다.

public: 이 접근성으로 선언된 구성원은 이 구성원을 포함하는 어셈블리 또는 포함하는 어셈블리를 참조하는 다른 어셈블리 내에서 볼 수 있습니다. 즉, 액세스는 제한되지 않습니다.

C# 7.2에서는 새로운 수준의 접근성이 추가되었습니다.

개인 보호:이 접근성으로 선언된 멤버는 포함 어셈블리 내의 포함 유형에서 파생된 유형 내에서 볼 수 있습니다.포함 유형에서 파생되지 않은 형식이나 포함 어셈블리 외부에서는 볼 수 없습니다. 즉, 액세스가 포함 어셈블리 내에서 파생된 유형으로 제한됩니다.

새 개인 보호 액세스 수정자의 샘플 코드를 포함하는 원본

다른 유형의 시각화를 만들었습니다.어쩌면 이것이 누군가를 이해하는 더 나은 방법일 수도 있습니다.

https://github.com/TropinAlexey/C-sharp-Access-Modifiers

여기에 이미지 설명 입력

공용 형식 또는 구성원은 동일한 어셈블리 또는 이를 참조하는 다른 어셈블리의 다른 코드로 액세스할 수 있습니다.유형의 공용 구성원의 접근성 수준은 유형 자체의 접근성 수준에 의해 제어됩니다.

private 형식 또는 멤버는 동일한 클래스 또는 구조체의 코드로만 액세스할 수 있습니다.

내부 유형 또는 구성원은 동일한 어셈블리의 파일 내에서만 액세스할 수 있습니다.

보호됨 형식 또는 멤버는 동일한 클래스 또는 해당 클래스에서 파생된 클래스의 코드로만 액세스할 수 있습니다.내부:유형 또는 멤버는 동일한 어셈블리의 모든 코드로 액세스할 수 있지만 다른 어셈블리에서는 액세스할 수 없습니다.즉, 내부 유형 또는 구성원은 동일한 컴파일의 일부인 코드에서 액세스할 수 있습니다.보호된 내부:형식 또는 구성원은 선언된 어셈블리의 모든 코드 또는 다른 어셈블리의 파생 클래스 내에서 액세스할 수 있습니다.

private protected 포함 어셈블리 내에서 선언된 클래스에서 파생된 형식으로 형식 또는 멤버에 액세스할 수 있습니다.

보호된 내부 보호된 내부 구성원은 현재 어셈블리 또는 포함 클래스에서 파생된 형식에서 액세스할 수 있습니다.

정적 한정자는 특정 개체가 아닌 형식 자체에 속하는 정적 멤버를 선언하는 데 사용됩니다.정적 한정자를 사용하여 정적 클래스를 선언할 수 있습니다.클래스, 인터페이스 및 구조체에서 필드, 메서드, 속성, 연산자, 이벤트 및 생성자에 정적 한정자를 추가할 수 있습니다.

C#11에서는 파일 액세스 수식자를 사용할 수도 있습니다.

파일 한정자는 선언된 파일에 대한 최상위 유형의 범위와 가시성을 제한합니다.파일 수정자는 일반적으로 소스 생성기에서 작성한 유형에 적용됩니다.파일 로컬 유형은 생성된 유형 간의 이름 충돌을 방지하는 편리한 방법을 원본 생성기에 제공합니다.

// In File1.cs:
file interface IWidget
{
    int ProvideAnswer();
}

file class HiddenWidget
{
    public int Work() => 42;
}

public class Widget : IWidget
{
    public int ProvideAnswer()
    {
        var worker = new HiddenWidget();
        return worker.Work();
    }
}

C#에 대한 모든 액세스 수식자의 설명

여기에 이미지 설명 입력

언급URL : https://stackoverflow.com/questions/614818/in-c-what-is-the-difference-between-public-private-protected-and-having-no

반응형