Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
46분 57초
이 글에서는 C#에서 타입, 메서드, 변수의 가시성과 접근성을 정의하는 접근 제한자에 대해 자세히 살펴보겠습니다. Tim Corey는 자신의 비디오 " C# 접근 제한자(public 및 private 외) - 무엇이며, 어떻게 사용하고, 모범 사례는 무엇인가 "에서 다양한 접근 제한자를 설명하고 콘솔 애플리케이션에서 실제 사용법을 보여줍니다.
이 글에서는 Tim이 다룬 내용을 설명하고, 이해를 돕기 위한 코드 예제도 함께 제공합니다. 제공된 타임스탬프를 통해 영상을 따라가면서 더욱 실감나는 경험을 할 수 있습니다.
팀 코리는 접근 제한자를 소개하며, 접근 제한자가 C#에서 누가 리소스를 보고 사용할 수 있는지 를 결정한다고 설명합니다. 일반적으로 사용되는 공용 및 개인 접근 제한자는 익숙하지만, Tim은 서로 다른 6가지 접근 제한자 와 그 사용 사례를 살펴봅니다.
팀은 다양한 접근 제어자가 어떻게 작동하는지 보여주기 위해 간단한 애플리케이션을 설치합니다. 이 애플리케이션은 콘솔 사용자 인터페이스와 데모 라이브러리로 구성되어 있으며, 둘 다 .NET Framework 로 작성되었습니다.
public class AccessDemo
{
private void PrivateDemo() { }
internal void InternalDemo() { }
public void PublicDemo() { }
}Public Class AccessDemo
Private Sub PrivateDemo()
End Sub
Friend Sub InternalDemo()
End Sub
Public Sub PublicDemo()
End Sub
End Classprivate 한정자는 해당 메서드, 필드 또는 속성에 대한 접근을 해당 클래스가 정의된 내부로만 제한합니다.
public class AccessDemo
{
private void PrivateDemo()
{
Console.WriteLine("Private method can only be accessed within this class.");
}
public void CallPrivateDemo()
{
PrivateDemo(); // Works because it's within the same class
}
}Public Class AccessDemo
Private Sub PrivateDemo()
Console.WriteLine("Private method can only be accessed within this class.")
End Sub
Public Sub CallPrivateDemo()
PrivateDemo() ' Works because it's within the same class
End Sub
End Class설명: The PrivateDemo 메서드는 AccessDemo 클래스 내에서만 접근할 수 있습니다. 영상에서 Tim은 다른 클래스가 같은 프로젝트에 있더라도 클래스 외부에서는 해당 클래스에 접근할 수 없다는 것을 보여줍니다.
모범 사례 : 클래스의 내부 작동 방식에 대한 접근을 제한하여 애플리케이션의 다른 부분에서 직접 수정할 수 없도록 하려면 private 키워드를 사용하십시오.
내부 접근 제한자를 사용하면 동일한 어셈블리(프로젝트) 내에서만 해당 메서드 또는 속성에 접근할 수 있습니다. 이는 private 접근 제한자보다 범위가 더 넓으며, 동일한 프로젝트 내의 모든 클래스를 포함합니다.
public class AccessDemo
{
internal void InternalDemo()
{
Console.WriteLine("Internal method is accessible within the same assembly.");
}
}Public Class AccessDemo
Friend Sub InternalDemo()
Console.WriteLine("Internal method is accessible within the same assembly.")
End Sub
End Class설명: The InternalDemo 메서드는 동일한 어셈블리 내의 모든 클래스에서 접근할 수 있지만, 다른 어셈블리에서는 접근할 수 없습니다. 영상에서 팀은 내부 접근 권한은 동일 프로젝트 내부에서는 허용하지만 외부에서는 접근을 차단한다는 것을 보여줍니다.
모범 사례 : 현재 어셈블리 내에서만 사용하도록 의도된 메서드 또는 속성(예: 외부 프로젝트에 노출되어서는 안 되는 헬퍼 함수 또는 유틸리티)에는 internal을 사용하십시오.
public 한정자를 사용하면 다른 클래스나 어셈블리에서 해당 메서드 또는 속성에 접근할 수 있습니다. 이는 가장 관대한 접근 권한 수준입니다.
public class AccessDemo
{
public void PublicDemo()
{
Console.WriteLine("Public method can be accessed from any class.");
}
}Public Class AccessDemo
Public Sub PublicDemo()
Console.WriteLine("Public method can be accessed from any class.")
End Sub
End Class설명: The PublicDemo 메서드는 동일한 어셈블리나 다른 어셈블리 내의 다른 클래스에서도 포함하여 어느 곳에서나 접근할 수 있습니다. Tim은 특히 라이브러리에서 메서드를 노출할 때 public이 가장 일반적인 접근 제한자임을 보여줍니다.
모범 사례 : API 엔드포인트 또는 널리 사용되는 유틸리티와 같이 애플리케이션의 다른 부분이나 외부 프로젝트에서 접근해야 하는 메서드 및 속성에는 public 키워드를 사용하세요.
protected 접근 제어자는 해당 제어자가 정의된 클래스 내에서는 물론, 파생 클래스(상속)에서도 해당 메서드 또는 속성에 접근할 수 있도록 합니다. 이 한정자는 객체 지향 프로그래밍, 특히 상속의 경우에 유용합니다.
public class AccessDemo
{
protected void ProtectedDemo()
{
Console.WriteLine("Protected method can be accessed within the class and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedDemo()
{
ProtectedDemo(); // Accessible because of inheritance
}
}Public Class AccessDemo
Protected Sub ProtectedDemo()
Console.WriteLine("Protected method can be accessed within the class and derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallProtectedDemo()
ProtectedDemo() ' Accessible because of inheritance
End Sub
End Class설명: The ProtectedDemo 메서드는 AccessDemo 클래스 및 이 클래스로부터 상속받는 모든 클래스에서 접근할 수 있습니다. Tim은 protected가 흔하지는 않지만 상속을 다룰 때 매우 유용하다고 설명합니다.
모범 사례 : 파생 클래스가 특정 메서드나 속성에 접근할 수 있도록 허용하되, 클래스 계층 구조 외부에서는 접근할 수 없도록 하려면 protected 키워드를 사용하십시오.
개인 보호 수정자는 개인 및 보호 규칙을 결합합니다. 이는 동일한 어셈블리 내의 정의 클래스 및 파생 클래스 내의 메서드 또는 속성에 대한 액세스를 제한합니다. 이는 protected에 비해 상속 기반 접근 제어에 대해 더 높은 수준의 보호와 더욱 엄격한 경계를 제공한다는 의미입니다.
public class AccessDemo
{
private protected void PrivateProtectedDemo()
{
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallPrivateProtectedDemo()
{
PrivateProtectedDemo(); // Accessible because of inheritance within the same assembly
}
}
public class UnrelatedClass
{
public void TestAccess()
{
// PrivateProtectedDemo(); // Error: Not accessible in unrelated classes
}
}Public Class AccessDemo
Private Protected Sub PrivateProtectedDemo()
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallPrivateProtectedDemo()
PrivateProtectedDemo() ' Accessible because of inheritance within the same assembly
End Sub
End Class
Public Class UnrelatedClass
Public Sub TestAccess()
' PrivateProtectedDemo() ' Error: Not accessible in unrelated classes
End Sub
End Class설명: The PrivateProtectedDemo 메서드는 AccessDemo로부터 상속받고 동일한 어셈블리에 존재하기 때문에 DerivedClass에서 접근할 수 있습니다. 그러나 UnrelatedClass에서는 이 클래스가 AccessDemo로부터 상속받지 않았기 때문에 접근할 수 없습니다.
모범 사례 : 동일한 어셈블리 내에서 상속 접근을 엄격하게 제어해야 할 경우에만 private protected 접근 제한자를 신중하게 사용하십시오. 이는 어셈블리 간에 메서드나 속성을 노출하면 캡슐화가 손상될 수 있는 시나리오에서 특히 유용합니다.
보호된 내부 접근 수정자는 보호된 접근 수정자 수준과 내부 접근 수정자 수준을 결합합니다. 이를 통해 동일한 어셈블리 또는 파생 클래스에서 해당 클래스가 다른 어셈블리에 있더라도 접근할 수 있습니다.
public class AccessDemo
{
protected internal void ProtectedInternalDemo()
{
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedInternalDemo()
{
ProtectedInternalDemo(); // Accessible due to inheritance
}
}Public Class AccessDemo
Protected Friend Sub ProtectedInternalDemo()
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.")
End Sub
End Class
Public Class DerivedClass
Inherits AccessDemo
Public Sub CallProtectedInternalDemo()
ProtectedInternalDemo() ' Accessible due to inheritance
End Sub
End Class설명: The ProtectedInternalDemo 메서드는 동일한 어셈블리 내에서 접근할 수 있으며, 이러한 클래스에서 파생된 클래스도 어셈블리와 상관없이 접근할 수 있습니다.
모범 사례 : 파생 클래스(다른 어셈블리에 있는 클래스)와 동일 어셈블리 내의 클래스 모두에게 메서드를 노출하되 모든 사람에게 노출하지 않으려는 경우 protected internal을 사용하십시오.
팀 코리는 접근 제한자를 사용하는 것의 중요성과 모든 것을 공개해서는 안 되는 이유에 대해 설명합니다. 모든 것을 공개하는 것이 편리해 보일 수 있지만, 데이터 유출, 버그, 개발 과정의 혼란 등 상당한 위험을 수반합니다. 접근 제한자는 정보를 보호하고, 의도치 않은 공개 접근을 방지하며, 코드베이스의 명확성을 제공하기 위해 존재합니다.
팀은 사회보장번호(SSN)나 신용카드 번호와 같은 민감한 정보를 공개해서는 안 되는 이유에 대해 설명합니다. 그는 공개 접근으로 인해 데이터 노출이 발생하는 "나쁜 클래스"의 예를 제시합니다.
잘못된 예:
public class User
{
public string SSN; // Anyone can access and modify it directly
}Public Class User
Public SSN As String ' Anyone can access and modify it directly
End Class좋은 예:
public class User
{
private string ssn;
public string GetMaskedSSN()
{
return "XXX-XX-" + ssn.Substring(ssn.Length - 4);
}
public void SetSSN(string value)
{
// Add validation if needed
ssn = value;
}
}Public Class User
Private ssn As String
Public Function GetMaskedSSN() As String
Return "XXX-XX-" & ssn.Substring(ssn.Length - 4)
End Function
Public Sub SetSSN(value As String)
' Add validation if needed
ssn = value
End Sub
End Class시작 시간: 35:11
팀은 비공개 메서드가 직접 접근해서는 안 되는 동작을 캡슐화하는 데 도움이 된다고 설명합니다. 그는 직원 퇴직 같은 더 큰 프로세스의 일환으로 DeleteUser 메서드의 예를 사용합니다.
잘못된 예:
public class UserManager
{
public void DeleteUser(int userId)
{
// Deletes the user without considering related processes
}
}Public Class UserManager
Public Sub DeleteUser(userId As Integer)
' Deletes the user without considering related processes
End Sub
End Class좋은 예:
public class UserManager
{
public void OffboardUser(int userId)
{
RevokeAccess(userId);
DeleteUser(userId); // Used privately as part of offboarding
}
private void DeleteUser(int userId)
{
// Internal logic to delete the user
}
private void RevokeAccess(int userId)
{
// Logic to revoke system access
}
}Public Class UserManager
Public Sub OffboardUser(userId As Integer)
RevokeAccess(userId)
DeleteUser(userId) ' Used privately as part of offboarding
End Sub
Private Sub DeleteUser(userId As Integer)
' Internal logic to delete the user
End Sub
Private Sub RevokeAccess(userId As Integer)
' Logic to revoke system access
End Sub
End Class접근 제한자는 데이터가 적절한 유효성 검사를 거쳐 설정되거나 검색되도록 보장함으로써 버그를 방지합니다. 팀은 Age 속성을 포함하는 예제로 이것을 설명합니다.
잘못된 예:
public class Person
{
public int Age; // Can be directly set to an invalid value
}Public Class Person
Public Age As Integer ' Can be directly set to an invalid value
End Class좋은 예:
public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value < 0 || value > 120)
throw new ArgumentOutOfRangeException("Age must be between 0 and 120.");
age = value;
}
}
}Public Class Person
Private _age As Integer
Public Property Age As Integer
Get
Return _age
End Get
Set(value As Integer)
If value < 0 OrElse value > 120 Then
Throw New ArgumentOutOfRangeException("Age must be between 0 and 120.")
End If
_age = value
End Set
End Property
End Class접근 제한자를 올바르게 사용하면 필요한 부분만 노출하여 개발을 간소화하고 혼란을 방지할 수 있습니다. 예를 들어, 수천 개의 메서드를 가진 애플리케이션에서 공개 메서드만 노출하면 개발자는 관련 옵션만 볼 수 있습니다.
예:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}Public Class MathLibrary
Public Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Public Function Subtract(a As Integer, b As Integer) As Integer
Return a - b
End Function
Private Sub LogCalculation(operation As String, result As Integer)
' Logging is internal and not exposed
End Sub
End ClassTim은 대규모 프로젝트의 경우 접근 제한자를 적절히 사용하면 라이브러리에서 필요한 부분만 노출되어 라이브러리를 사용하는 개발자의 인지 부하를 줄일 수 있다고 설명합니다.
예:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}Public Class MathLibrary
Public Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Public Function Subtract(a As Integer, b As Integer) As Integer
Return a - b
End Function
Private Sub LogCalculation(operation As String, result As Integer)
' Logging is internal and not exposed
End Sub
End Class이러한 접근 제한자를 올바르게 사용하면 자신과 다음 사람의 업무를 더 쉽게 만들 수 있습니다.
팀 코리는 C# 접근 제한자를 마스터하는 방법에 대한 명확하고 실용적인 가이드를 제공하며, 이를 효과적으로 사용하여 안전하고 유지 관리하기 쉬우며 전문적인 애플리케이션을 만드는 방법을 보여줍니다. 그의 상세한 설명과 실제 사례 덕분에 모든 수준의 개발자들이 이 주제를 쉽게 이해할 수 있습니다.
더 자세한 내용을 이해하고 이러한 개념이 실제로 어떻게 적용되는지 보려면 Tim의 전체 영상을 시청하고 그의 채널 에서 C# 및 기타 프로그래밍 주제에 대한 유용한 콘텐츠를 살펴보세요. 개발 실력 향상에 진지한 사람이라면 반드시 방문해야 할 자료입니다!
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy