2. 클래스 라이브러리 (Class library)
클래스 라이브러리는 대게 독립적으로 실행될 수 있는 Application보다는 다른 Application에서 기능을 활용할 수 있는 DLL과 같은 형태로 배포되는데 .NET이 가장 대표적인 '클래스 라이브러리'의 모음이라고 할 수 있습니다.
Visual Studio Code를 사용하는 경우 프로젝트를 '클래스 라이브러리'형태로 생성하려면 'classlib'옵션을 사용해 프로젝트를 생성해야 합니다.
dotnet new classlib -o mylibrary
|
예제에서 프로젝트의 이름은 'mylibrary'로 하였습니다.
프로젝트를 생성한 뒤 프로젝트의 *.csproj파일을 보면
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
TargetFramework가 net6.0으로 설정되어 있는 것을 볼 수 있습니다. 이 말은 해당 클래스 라이브러리는 오직 net6.0에서만 호환될 수 있는 라이브러리가 된다는 것을 의미합니다. 만약 호환성에 대한 조정이 필요하다면 아래와 같이 설정을 바꿔줄 수 있습니다.
<TargetFramework>netstandard2.0</TargetFramework>
프로젝트는 Class1.cs라는 파일을 자동으로 생성하는데 이 파일을 Car.cs로 변경하고 아래와 같이 파일을 수정합니다.
namespace mylibrary;
public class Car
{
}
class Car에서 Car가 클래스 이름이 됩니다. public는 접근 제한자로서 외부에서 해당 클래스에 접근할 수 있도록 해주는 키워드입니다. 만약 public를 생략한다면 internal이 기본이 되는데 internal은 같은 Assembly안에서만 접근할 수 있는 클래스가 됩니다.
namespace mylibrary는 Car라는 클래스가 mylibrary라는 네임스페이스에 속한다는 것을 보여주는데 이전 버전과는 달리 namespace가 세미클론(;) 문자로 종료되어 있습니다. 이것은 .NET 6/C# 10부터 적용된 것으로 'file-scoped namespace'라고 하며 기존과 달리 중괄호({})를 사용하지 않기 때문에 코드가 구조적으로 좀 더 간결해질 수 있습니다.
● Member
예제에서 Car클래스는 아직 어떠한 멤버도 가지지 않은 클래스입니다. 멤버는 Field나 Method가 될 수 있으며 각각은 그 특징에 따라 다른 세부적인 것으로 나뉘어 질 수 있습니다.
먼저 Field에 대한 것입니다. Field는 데이터를 저장하기 위한 용도로 사용되며 아래와 같은 것으로 구분됩니다.
Constant | 값이 바뀌지 않는 것을 의미하며 컴파일러는 값을 있는 그대로 취급합니다. |
Read-only | 값이 바뀌지 않는 것을 의미하지만 Constant와는 달리 Class의 인스턴스를 생성할때 필요한 값을 부여할 수 있고 인스턴스가 생성되고 나면 이 후 부터 값은 고정됩니다. |
Event | 하나 또는 그 이상의 Method를 참조하는 것으로 이때 Method는 Application에서 사용자가 마우스로 버튼을 클릭하는 등의 어떤 사건이 발생할때 실행되는 Method가 됩니다. |
Method는 함수를 의미하는데 Class안에 있는 함수를 Method라고 표현합니다.
Constructor | '생성자'라고 하며 클래스의 인스턴스를 생성해 메모리에 할당하기 위한 new 키워드가 사용될때 실행되는 Method입니다. |
Property | 데이터를 할당하거나 할당된 데이터를 가져오는 경우에 실행되는 Method이며 Field를 캡슐화하는데 선호되는 방법입니다. |
Indexer | 객체자체를 배열로 표현하는 대괄호([])를 사용해 데이터를 설정하거나 가져올때 실행되는 메서드입니다. |
Operator | +나 -와 같은 연산자를 객체에 적용할때 실행되는 메서드입니다. |
● 인스턴스 생성하기
'인스턴스'를 살펴보기전 먼저 다른 프로젝트를 생성해 이전에 만든 클래스 라이브러리 프로젝트를 참조로 추가해야 합니다. 이를 위해 아래 명령으로 Console App프로젝트를 생성합니다.
dotnet new console -o myapp |
예제는 새로운 Console App프로젝트를 myapp이라는 이름으로 생성합니다.
그런다음 myapp프로젝트의 myapp.csproj파일을 아래와 같이 수정해 이전에 만든 mylibrary프로젝트를 참조하도록 합니다. (참조 경로는 각자의 위치에 맞게 적절히 수정되어야 합니다.)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../mylibrary/mylibrary.csproj" />
</ItemGroup>
</Project>
myapp을 빌드하여 정상적으로 빌드가 진행되는지를 확인합니다. 명령의 실행은 myapp프로젝트 폴더에서 수행해야 합니다.
dotnet build |
정상적으로 진행되었다면 문제는 없는 것이므로 myapp의 Program.cs파일을 열어 mylibrary의 Car클래스의 인스턴스를 생성하고 해당 객체의 이름을 표시하도록 수정합니다.
using mylibrary;
Car c = new();
Console.WriteLine(c.ToString());
//mylibrary.Car
이미 언급한 것처럼 new키워드는 객체를 위한 메모리를 할당하고 내부의 데이터를 초기화합니다.
● Object
Car 클래스는 명시적으로 상속하는 클래스를 지정하지 않았지만 기본적으로 System.Object로 부터 상속받게 되며 이를 피할 수는 없습니다. 예제에서 ToString()은 Object클래스에 존재하는 것으로 모든 클래스는 Object로부터 자동적으로 상속받게 되므로 사용 가능한 메서드입니다. 기본적으로 Object의 ToString() 메서드는 자신의 네임스페이스와 이름을 출력합니다.
클래스가 Object로 부터 상속되는 것은 명시하지 않아도 그렇게 되는 것이지만 코드상에서 이를 명확히 하려면 다음과 같이 클래스를 정의할 수도 있습니다.
namespace mylibrary;
public class Car : System.Object //또는 object (System.Object의 별칭)
{
}
실제 위와 같이 클래스를 정의하고 System.Object에서 Object에 커서를 이동시킨 뒤 F12키를 눌러보면 Object에 존재하는 몇 가지 Member를 볼 수 있는데 그중에서 ToString() 메서드도 확인할 수 있습니다.
#region Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll
#endregion
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
namespace System
{
[__DynamicallyInvokableAttribute]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Object
{
[__DynamicallyInvokableAttribute]
[NonVersionableAttribute]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Object();
[__DynamicallyInvokableAttribute]
[NonVersionableAttribute]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~Object();
[__DynamicallyInvokableAttribute]
public static bool Equals(Object objA, Object objB);
[__DynamicallyInvokableAttribute]
[NonVersionableAttribute]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static bool ReferenceEquals(Object objA, Object objB);
[__DynamicallyInvokableAttribute]
public virtual bool Equals(Object obj);
[__DynamicallyInvokableAttribute]
public virtual int GetHashCode();
[__DynamicallyInvokableAttribute]
[SecuritySafeCritical]
public Type GetType();
[__DynamicallyInvokableAttribute]
public virtual string ToString();
[__DynamicallyInvokableAttribute]
[SecuritySafeCritical]
protected Object MemberwiseClone();
}
}
'.NET > C#' 카테고리의 다른 글
[C#] C#과 OOP(Object-Oriented Programming) - 4. Method (메서드) (0) | 2022.06.24 |
---|---|
[C#] C#과 OOP(Object-Oriented Programming) - 3. 필드(Field) (0) | 2022.06.24 |
[C#] C#과 OOP(Object-Oriented Programming) - 1. 객체지향프로그래밍 개념 (0) | 2022.06.24 |
[C#] 예외처리 (0) | 2022.06.24 |
[C#] 형변환 (0) | 2022.06.24 |