Category Archives: C# Programming

Class & Inheritance

Indexer
http://dis.dankook.ac.kr/lectures/hci09/entry/Indexer

Property (속성)
http://dis.dankook.ac.kr/lectures/hci09/entry/Property

Method overloading (메소드 오버로딩) Method overriding (메소드 오버라이딩)
http://dis.dankook.ac.kr/lectures/hci09/entry/Method-Overloading

Abstract Class (추상 클래스)
http://dis.dankook.ac.kr/lectures/hci09/entry/Abstract-class

Sealed Class (봉인 클래스)
http://dis.dankook.ac.kr/lectures/hci09/entry/Sealed-Class

Class

protected
-protected 접근 지정자를 사용한 멤버 필드와 메소드는 파생 클래스에서는 사용가능하나 클래스 외부에서는 호출하지 못함


static
-static field는 전역 데이터로 클래스당 하나만 할당됨
-클래스명.정적필드명 형태로 사용
-static method는 class method나 static member field 조작을 위한 메소드
-static method는 instance field는 접근 불가능

constructor
-default constructor (기본 생성자)
-constructor overloading (생성자 오버로딩) 생성자를 여러 가지 형태로 정의
-constructor initializer (생성자 초기화 목록) 생성자들 사이의 정의가 비슷한 경우 코드를 간략하게 만들기 위해 사용

-private constructor (private 생성자) 정적 멤버만 포함하는 클래스에서 사용하며 클래스가 인스턴스화 될 수 없음을 분명히 하기 위해 private 접근 지정자를 사용
-static constructor (static 생성자)  정적 데이터 멤버를 초기화하는데 사용

destructor
-객체가 소멸될 때 필요한 정리 작업을 정의하는 부분

static constructor와 instance constructor 비교

C#은 두 가지 종류의 constructor, 즉 class constructor(static constructor), instance constructor(non-static constructor)를 지원한다.
 
static constructor
-static constructor는 static data member를 초기화하는데 사용
-static constructor는 접근 지정자를 쓸수 없음
-static constructor는 인자를 가질 수 없음
-static constructor는 non-static data member를 접근할 수 없음


// Test.cs
class Test
{
    //Declaration and initialization of static data member
    private static int id = 5;
    public static int Id
    {
        get
        {
            return id;
        }
    }

    public static void print()
    {
        Console.WriteLine(“Test.id=” + id);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test.print(); // 정적 메소드를 사용하여 Test.id를 출력
    }

}


Test.id=5


 


// Test1.cs
class Test1
{
    private static int id;

    // static constructor를 사용하여 Test.id값에 따라서 Test1.id를 지정
    static Test()
    {
        if
( Test.Id < 10 )
        {
            id = 20;
        }
        else
        {
            id = 100;
        }
    }

    public static void print()
    {
        Console.WriteLine(“Test.id=” + id);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test1.print(); // 정적 메소드를 사용하여 Test.id를 출력
    }
}


Test.id=20 // 정적 생성자 내에서 Test.id=5였기때문에 Test.id=20

instance constructor
-instance
constructor는 new 키워드를 사용하여 객체 생성에 사용
-instance constructor는 일반적으로  constructor라고 불림
constructor initializer는 생성자들 코드를 간략하게 만들기 위해 사용


public class MySimpleClass
{
    public MySimpleClass (int x)
    {
        Console.WriteLine (x);
    }
}
// 위의 코드는 컴파일러에서 아래의 코드처럼 해석
public
class MySimpleClass
{
    public MySimpleClass (int x) : base()
    {
        Console.WriteLine (x);
    }
}


public class MyClass
{
    private ArrayList col;
    private string name;
    public MyClass() : this(0,””) // 생성자 초기화목록을 사용하여 기본 생성자 지정
    {
    }
    public MyClass(int initialCount) : this (initialCount, “”)
    {
    }
    public MyClass(int initialCount, string name)
    {
        col = (initialCount > 0) ? new ArrayList(initialCount) : new ArrayList();
        this.name = name;
    }
}

-default constructor가 지정되어 있지 않다면 컴파일러에서 자동 생성해줌


public class MySimpleClass
{
    int someMemberVariable;
}
// 위의 코드를 컴파일러에서 아래와 같이 해석함
public class MySimpleClass
{
    int someMemberVariable;
               
    public MySimpleClass() : base()
    {
    }
}

-constructor는 상속되지 않음
public class MyBaseClass
{
    public MyBaseClass (int x)
    {
    }
}

public class MyDerivedClass : MyBaseClass
{
    // This constructor itself is okay – it invokes an
    // appropriate base class constructor
    public MyDerivedClass () : base (5)
    {
    }
             
    public static void Main()
    {
        new MyDerivedClass (10); // ERROR: MyDerivedClass는 인자를 받는 생성자가 없음
    }
}

singleton pattern과 static class 비교

공용 데이터를 저장하여 사용하고자 할 때, singleton 패턴이나 static 클래스를 사용한다.

1. 싱글톤 패턴 (Singleton design pattern)
-싱글톤 패턴이란 single instance object(해당 클래스의 인스턴스 하나)가 만들어지고, 어디서든지 그 싱글톤에 접근할 수 있도록 하기 위한 패턴


/// Sample singleton object.
public sealed class SiteStructure
{
    /// This is an expensive resource we need to only store in one place.
    object[] _data = new object[10];

    /// private constructor를 사용해서 static readonly로 객체 하나를 생성.
    static readonly SiteStructure _instance = new SiteStructure();

    /// 그 싱글톤에 접근하기 위한 property를 제공.
    public static SiteStructure Instance
    {
        get { return _instance; }
    }

    /// private constructor, 즉 외부에서는 이 생성자를 부를 수 없음.
    private SiteStructure()
    {
        // Initialize members, etc. here.
    }
}
// 싱글톤 객체를 인자로 전달 가능
SiteStructure site = SiteStructure.Instance;
OtherFunction(site); // Use singleton as parameter.



2. 정적 클래스 (Static class)
-static 키워드를 사용한 정적 클래스는 정적 멤버만 포함 가능
-정적 클래스는 new 키워드를 사용하여 정적 클래스의 인스턴스를 생성할 수 없음
-정적 클래스는 봉인 클래스 (sealed class) 임
-static 클래스는 single-instance, global 데이터를 저장하여 사용하는 용도로 적당
-그러나, 싱글톤은 인자(parameter)나 객체(object)로 사용가능하나 정적클래스는 불가능


/// Static class example.
static public class SiteStatic
{
    /// The data must be a static member in this example.
    static object[] _data = new object[10];

    /// C# doesn’t define when this constructor is run, but it will likely
    /// be run right before it is used.
    static SiteStatic()
    {
        // Initialize all of our static members.
    }
}


3. 싱글톤(Singleton)을 Interface와 함께 사용


/// Stores signatures of various important methods related to the site.
public interface ISiteInterface
{
};

/// ISiteInterface를 상속받은 SiteStructure 싱글톤
class SiteStructure : ISiteInterface
{
    // Implements all ISiteInterface methods.
    // 생략..
}

/// 테스트
class TestClass
{
    public TestClass()
    {
        // 싱글톤 객체를 ISiteInterface를 받는 함수에 인자로 전달.
        SiteStructure site = SiteStructure.Instance;
        CustomMethod((ISiteInterface)site);
    }

    /// Receives a singleton that adheres to the ISiteInterface interface.
    private void CustomMethod(ISiteInterface interfaceObject)
    {
        // Use the singleton by its interface.
    }
}



참고: http://dotnetperls.com/singleton-static

pass by value와 pass by reference와 pass by output 비교

pass value type by value (값형식을 값에 의한 전달)


static void Square1(int x)
{
     x *= x;
     Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     Square1(i);
     Console.WriteLine(“i={0}”, i);
}

i=5
The value inside the method: 25
i=5

pass reference type by value (참조형식을 값에 의한 전달)
-copy of reference가 전달


static void ChangeArray1(int[] arr)
{
     arr[0]=888;       // 원본 배열의 첫번째 값은 888로 변경
     arr = new int[5] {-3, -1, -2, -3, -4}; // local 변수 재지정
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray1(myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=888


pass value type by reference (값형식을 참조에 의한 전달)
ref 키워드 사용


static void Square2(ref int x)
{
     x *= x;
     Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     Square2(ref i);
     Console.WriteLine(“i={0}”, i);
}

i=5
The value inside the method: 25
i=25


pass reference type by reference (참조형식을 참조에 의한 전달)
ref 키워드 사용


static void ChangeArray2(ref int[] arr)
{
     arr[0]=888;       // 원본 배열의 첫번째 값은 888로 변경
     arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 다시 변경
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray2(ref myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=-3


pass value type by output (값형식을 output에 의한 전달)
out 키워드 사용


static void Square3(int x, out int result)
{
     result = x*x;
     Console.WriteLine(“The value inside the method: {0}”, result);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     int result;
     Square3(i, out result);
     Console.WriteLine(“result={0}”, result);
}

i=5
The value inside the method: 25
result=25


pass reference type by output (참조형식을 output에 의한 전달)
out 키워드 사용


static void ChangeArray3(out int[] arr)
{
     //arr[0]=888;       // use of unassigned out parameter ‘arr’ ERROR
     arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 변경
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray3(out myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=-3


참조: http://msdn.microsoft.com/en-us/library/0f66670z(VS.71).aspx

0부터 100까지 숫자만 입력받기


int value;  // needed for TryParse
string str; // needed for ReadLine


Console.Write(“0부터 100까지 숫자를 입력하세요: “);
str = Console.ReadLine();
while ((!int.TryParse(str, out value)) || (value < 0 || value > 100))
{
        Console.Write(“다시 0부터 100까지 숫자를 입력하세요: “);
        str = Console.ReadLine();
}
int result = int.Parse(str);
Console.WriteLine(“입력된 숫자=” + result);