'프로그래밍/C#'에 해당되는 글 5건

  1. 2012.08.29 C#으로 오라클접속 by 초코송송이
  2. 2012.08.28 C#으로 MySql 접속 by 초코송송이
  3. 2012.08.28 C#으로 Active Directory 접근 by 초코송송이
  4. 2012.05.10 C#의 객체지향 by 초코송송이
  5. 2012.05.08 C#의 기본문법 by 초코송송이

1.Oracle Data Access Components for Windows를 다운로드한다.

http://www.oracle.com/technetwork/indexes/downloads/index.html?ssSourceSiteId=ocomen

=>설치할 때, 필수항목으로 Instant Client가 설치되는데 이미 설치되어 있어도 다시 하도록 되어있었음..;;

2. using Oracle.DataAccess.Client;

string oradb = "Data Source=(DESCRIPTION="              
              + "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.xxx)(PORT=1521)))"
                //+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl.xxxx.com)));"
                + "(CONNECT_DATA=(SERVER=DEDICATED)(SID=ORCL)));"
                + "User Id=user;Password=password;";//service_name은 전역데이터베이스이름
                       
using (OracleConnection conn = new OracleConnection(oradb))
{
    try
    {
        conn.Open();

        using (OracleCommand cmd = new OracleCommand())
        {
            cmd.Connection = conn;
            cmd.CommandText = "select * from " +  tablename;

            OracleDataReader dr = cmd.ExecuteReader();                                                             

            while(dr.Read())
            { 
                 MessageBox.Show(dr.GetString(1));

....

      }

      cmd.CommandText = "insert into " + tablename + " (column1, column2, column3)"
                                                       + " VALUES('" + val1 + "', '" + val3 + "', '" + val3 + "')";

      int Res = cmd.ExecuteNonQuery();
      if (Res == 1)
      {
          System.Diagnostics.Trace.WriteLine("insert 성공");
      }
      else
      {
          System.Diagnostics.Trace.WriteLine("insert 실패");
      }

        }

    }
    catch (OracleException ex) // catches only Oracle errors
    {
        switch (ex.Number)
        {
            case 1:
                MessageBox.Show("Error attempting to insert duplicate data.");
                break;

            case 12545:
                MessageBox.Show("The database is unavailable.");
                break;

            default:
                MessageBox.Show("Database error: " + ex.Message.ToString());
                break;
        }
    }

    catch (Exception ex) // catches any other error
    {
        MessageBox.Show(ex.Message.ToString());
    }
    finally
    {
         // Don't need conn.Close() because the using takes care of it.
    }
}

'프로그래밍 > C#' 카테고리의 다른 글

C#으로 MySql 접속  (0) 2012.08.28
C#으로 Active Directory 접근  (0) 2012.08.28
C#의 객체지향  (0) 2012.05.10
C#의 기본문법  (0) 2012.05.08
Posted by 초코송송이
l

1. mysql-connector-net 설치

http://www.mysql.com/downloads/connector/net/

2. Reference에 추가 - MySql.Data

3. 소스에 적용

using MySql.Data;
using MySql.Data.MySqlClient;

static string DBConnectString = "Data Source=192.168.0.xxx;Database=db_name;" + "User Id=userid;Password=password" + ";charset=utf8";

MySqlConnection Con = new MySqlConnection();
Con.ConnectionString = DBConnectString;
            
try
{
    Con.Open();
         
    MySqlCommand Command = new MySqlCommand("SELECT * FROM table_name", Con);
    MySqlDataReader DataReader;
    DataReader = Command.ExecuteReader();

    while (DataReader.Read())
    {
         MappingTable MappingT = new MappingTable();
         MappingT.MappingNumber = string.Format("{0}", DataReader["table_column1"]);
         MappingT.UserId = string.Format("{0}", DataReader["table_column2"]);
         MappingT.SIP = string.Format("{0}", DataReader["table_column3"]);
         MappingTList.Add(MappingT);
    }
    DataReader.Close();
    Con.Close();
}

catch (MySqlException ex)
{
    MessageBox.Show(ex.ToString());
}

'프로그래밍 > C#' 카테고리의 다른 글

C#으로 오라클접속  (0) 2012.08.29
C#으로 Active Directory 접근  (0) 2012.08.28
C#의 객체지향  (0) 2012.05.10
C#의 기본문법  (0) 2012.05.08
Posted by 초코송송이
l

1. Active Directory에 조직구성단위 추가

using System.DirectoryServices;

DirectorySearcher DSESearcher = new DirectorySearcher();
DirectoryEntries DEntries = DSESearcher.SearchRoot.Children;                
DirectoryEntry ou2 = DEntries.Add("OU=" + OrgName, "organizationalUnit");
ou2.CommitChanges();
ou2.Close();

2. 조직구성단위 열거

DirectorySearcher DSESearcher = new DirectorySearcher();
DirectoryEntries DEntries = DSESearcher.SearchRoot.Children;
List<string> listOU = new List<string>();

foreach (DirectoryEntry de in DEntries)
{
    if (de.Name.CompareTo("OU") > 0)
    {
        listOU.Add(de.Name.Remove(0, 3));//OU=구성단위이름

     }                
}    

3. 조직구성단위에서 사용자 추가

DirectorySearcher DSESearcher = new DirectorySearcher();
string RootDSE;
try
{
    RootDSE = DSESearcher.SearchRoot.Path;
}
catch
{
    System.Windows.MessageBox.Show("Active Directroy를 찾을수 없습니다.");
    return;
}

//조직구성단위 목록을 미리 가지고 와서 콤보박스에서 선택             
RootDSE = RootDSE.Insert(7, "OU="+ comboBoxOU.SelectedValue +",");
DirectoryEntry myDE = new DirectoryEntry(RootDSE);

//선택한 조직구성단위 아래에 사용자 추가

DirectoryEntry usr = myDE.Children.Add("CN=" + textBoxFName.Text + " " + textBoxGName.Text, "user");
 
//계정 - Windows 2000 이전버전 사용자 로그온 이름
usr.Properties["samAccountName"].Value = textBoxLogonName.Text;
//일반 - 표시이름
usr.Properties["displayName"].Value = textBoxFName.Text + " " + textBoxGName.Text;
//일반 - 이름
usr.Properties["givenname"].Value = textBoxGName.Text;
//일반 - 성
usr.Properties["sn"].Value = textBoxFName.Text; //family name
//계정 - 사용자 로그온 이름
usr.Properties["userPrincipalName"].Value = textBoxLogonName.Text + "@xxxxxx.com";
//조직 - 회사
if (textBoxCompany.Text.Length > 0)
    usr.Properties["company"].Value = textBoxCompany.Text;
//일반 - 전화 번호
if (textBoxTelNum.Text.Length > 0)
    usr.Properties["telephoneNumber"].Value = textBoxTelNum.Text;
//조직 - 직함
if (textBoxTitle.Text.Length > 0)
    usr.Properties["title"].Value = textBoxTitle.Text;
//조직 - 부서
if (textBoxDepartment.Text.Length > 0)
    usr.Properties["department"].Value = textBoxDepartment.Text;
//일반 - 전자 메일
if (textBoxMail.Text.Length > 0)
    usr.Properties["mail"].Value = textBoxMail.Text;

usr.CommitChanges();

usr.Invoke("SetPassword", textBoxPassword.Text);
//usr.Invoke("SetPassword", new object[] { textBoxPW.Text });

int val = (int)usr.Properties["userAccountControl"].Value;
usr.Properties["userAccountControl"].Value = val & ~0x2; //ADS_UF_NORMAL_ACCOUNT;
usr.CommitChanges();

myDE.Close();
usr.Close();

//(조직구성단위:OU, 사용자:CN)

'프로그래밍 > C#' 카테고리의 다른 글

C#으로 오라클접속  (0) 2012.08.29
C#으로 MySql 접속  (0) 2012.08.28
C#의 객체지향  (0) 2012.05.10
C#의 기본문법  (0) 2012.05.08
Posted by 초코송송이
l

1. 객체지향의 기본

 

1-1) 오버로딩(Overloading)

 

1) 오버로딩의 정의

- 하나의 이름으로 여러개의 함수를 만드는 기법

 

2) 오버로딩 함수를 만드는 규칙

- 반드시 매개변수의 개수와 매개변수의 형이 달라야한다.

 

3) 오버로딩 함수의 예

- public int plus(int a, int b) { ... }

- public float plus(float a, float b) { ... }

- public double plus(double a, double b) { ... }

 

1-2) 연산자 오버로딩(Operator Overloading)

 

1) 연산자 오버로딩(Operator Overloading)

- 연산자를 중복정의 하는 것: 일반적인 연산자를 생각하면 더하기 빼기 등 값에 대한 연산이다. 하지만 이러한 연산자를 객체들 사이의 연산으로 차원을 높여주는 것이 연산자 오버로딩이다.

 

2) 연산자 오버로딩의 예

 

class Top {

public int a = 0;

public int b = 0;

public Top(int a, int b) {

this.a = a;

this.b = b;

}

public static Top operator+(Top t1, Top t2) {

int m = t1.a + t2.a;

int n = t1.b + t2.b;

return new Top(m, n);

}

}

 

=> operator+ 함수의 개념적 호출

Top s1 = new Top(3, 5);

Top s2 = new Top(7, 16);

Top s3 = s1 + s2;

 

=> operator+ 함수의 실제 호출

Top s1 = new Top(3, 5);

Top s2 = new Top(7, 16);

Top s3 = s1 + s2;

 

◈ 오버로딩이 불가능한 연산자

- ?    .    =     is    new   sizeof    typeof    ||    []    ()    &&    ->    +=    -=    ?: 등

 

 

1-3) 상속(Inheritance) 

1) 상속(Inheritance) 

- 만들어둔 클래스를 다시 사용할수 있는 방법을 말한다.

 

2) 기본적인 상속 방법

public class HelloForm: Form {

..

}

 => HelloForm 클래스에서 Form 클래스를 상속받음

 

- 상위 클래스를 기본 클래스(Base Class)라고 하며, 하위 클래스(Sub Class)를 파생 클래스(Derived Class)라고 한다.

- 상속을 하면 상위 클래스의 능력을 하위 클래스에서 이용할 수 있다.

 

3) 상속 금지 키워드 sealed

public sealed class Father {

public void SayFather() {

..

}

}

 

=> Father 클래스는 상속을 할 수 없다.

 

1-4) 생성자

 

1) 생성자 함수

- 생성자 함수는 메모리가 생성된 직후 가장 먼저 호출되는 함수이다.

 

2) 생성자의 특징

- 생성자는 리턴타입이 없다.

- 생성자의 이름은 클래스의 이름과 동일하다.

- new 연산자가 힙 영역에 해당 클래스의 메모리를 생성한 직후 호출된다.

 

public class ConstructTest{

public ConstructTest() { // 생성자

     ..

}

}

 

1-5) 소멸자

 

1) 소멸자

- 객체의 메모리가 제거될 때 호출되는 함수

 

2) 소멸자의 특징

- 객체가 소멸되기 직전에 호출되어 객체에 부여된 메모리의 회수를 담당

- 실제적으로 메모리의 회수여부는 가비지 콜렉터가 담당한다.

 

public class DestructorTest {

public DestructorTest() {}

~DestructorTest() { //소멸자

Console.WriteLine("나는 소멸자");

}

public static void Main() {

DestructorTest a = new DestructorTest();

}

}

 

1-5) internal과 protected internal 접근자

 

1) 논리적 접근 제한자

- 기준: 클래스 계층 구조에서 접근을 제한

- public, private, protected

 

2) 물리적 접근 제한자

- 기준: 어셈블리 단위로 접근을 제한

- internal

 

3) internal 접근자

- 하나의 Assembly 내에서만 접근을 허락하는 접근자

- 같은 Assembly 안에 있어야 접근이 가능하다.

 

4) protected internal

- 어셈블리가 다르더라도 상속을 받은 하위 클래스에서 상위 클래스의 internal에 접근 가능하게 하기 위해서 protected internal을 제공한다.

 

1-6) 오버라이딩(Overriding) 

 

1) 오버라이딩의 종류

- new 키워드를 이용한 재정의

- virtual, override키워드를 이용한 재정의

 

2) virtual, override, new의 관계

- virtual : 하위 클래스에서 재정의해서 사용할 것을 표시

- override : 상위 클래스에서 virtual로 표시된 함수를 재정의 할 때 사용

- new : 상위 클래스의 함수를 완전히 무시할 때 사용

 

3) new 키워드를 이용하여 함수를 재정의한 후 업캐스팅 했을 때

- 업캐스팅 되었을 때 상위 클래스는 상위 클래스 내의 함수만을 호출한다.

 

class Base {

public void MethodA() {

Console.WriteLine("Base Method()");

}

}

class SimpleNew: Base {

new public void MethodA() {

Consol.WriteLine("SimpleNew Method()");

}

public static void Main() {

SimpleNew m = new SimpleNew();

m.MethodA(); // SimpleNew 메서드 호출

 

Base b = m;

b.MethodA(); // Base 메서드 호출

}

}

 

4) virtual 키워드를 이용하여 함수를 재정의 한 후 업캐스팅 했을 때

- 상위 클래스의 이름으로 하위 클래스의 함수를 호출하는 것이 된다.

 

class Base {

virtual public void MethodA() {

Console.WriteLine("Base Method()");

}

}

class SimpleNew: Base {

override public void MethodA() {

Consol.WriteLine("SimpleNew Method()");

}

public static void Main() {

SimpleNew m = new SimpleNew();

m.MethodA(); // SimpleNew 메서드 호출

 

Base b = m;

b.MethodA(); // SimpleNew 메서드 호출

}

}

 

1-7) this, 생성자를 호출하는 this()

 

1) this

- this란 자기자신을 참조하는 가상의 참조 변수이다. (this.멤버이름)

 

2) 생성자를 호출하는 this()

- 자신의 생성자를 호출할 때도 사용

- 자신의 생성자를 재사용하기 위해서 생성자를 호출하는 방법을 제공

 

3) this()를 사용하는 이유

- 생성자의 중복을 피하기 위해서

 

4) this() 생성자의 특징

- 생성자 내에서 this()를 호출한다면 this()를 이용한 생성자가 먼저 처리된 후 현재의 생성자가 처리된다.

 

using System;

public class ThisSelf {

private string name;

private int age;

public ThisSelf() : this("이름없음") {

Console.WriteLine("매개변수가 없는 생성자");

}

public ThisSelf(string name) : this(name, -1) {

Console.WriteLine("매개변수가 1개 있는 생성자");

}

public ThisSelf(string name, int age) {

this.name = name;

this.age = age;

Console.WriteLine("name: " + name + " number: " + age);

Console.WriteLine("매개변수가 2개 있는 생성자");

}

public static void Main() {

ThisSelf ts1 = new ThisSelf();

ThisSelf ts2 = new ThisSelf("홍길동");

ThisSelf ts3 = new ThisSelf("김삿갓", 50);

}

}

출력:

name: 이름없음 number: -1

매개변수가 2개 있는 생성자

매개변수가 1개 있는 생성자 

매개변수가 없는 생성자

name: 홍길동 number: -1

매개변수가 2개 있는 생성자

매개변수가 1개 있는 생성자

name: 김삿갓 number: 50

매개변수가 2개 있는 생성자

 

1-8) base 키워드, base()

 

1) base 키워드

- 재정의한 상위 클래스의 함수를 호출할 때 사용

 

using System;

public class NewFather {

public virtual void OverrideFunc() {

Console.WriteLine("아버지의 함수");

}

}

public class NewSon : NewFather {

public override void OverrideFunc() {

Console.WriteLine("아들의 재정의 함수");

}

public void TestFunc() {

base.OverrideFunc(); //NewFather의 메서드 호출

}

public static void Main() {

NewSon ns = NewSon();

ns.OverrideFunc(); // NewSon의 함수 호출

ns.TestFunc(); // TestFunc() 내에서 NewFather의 함수 호출

}

}

 

2) 상위 클래스의 생성자를 호출하는 base()

- 생성자 내에서 상위 클래스의 생성자를 호출하기 위해 사용한다.

- 상위 클래스 생성자에 매개변수가 존재하면 생성자의 매개변수의 형과 개수를 맞추어 주어야만 호출 가능하다.

 

using System;

public class BaseFather {

private stsring name;

public BaseFather(string name) {

this.name = name;

Console.WriteLine("BaseSon : {0}", name);

}

}

public class BaseSon : BaseFather {

public BaseSon(string str) : base(str) {

}

public static void Main() {

BaseSon s = new BaseSon("Base Test Problem");

}

}

출력:

BaseSon : Base Test Problem

 

 

2. 다형성

 

2-1) 다형성(Polymorphism)

1) 다형성(Polymorphism)이란?

- 다형성이란 하나로 여러가지의 일을 하는 것을 말한다.

 

2) 다형성이 적용되는 곳

- 오버로딩(Overloading)

- 오버라이딩(Overriding)

- 업캐스팅(Upcasting)

- 다운캐스팅(Downcasting)

- 추상 클래스(Abstract Class)의 상속 관계

- 인터페이스(Interface)의 상속 관계

 

3) 다형성을 지원하기 위한 도구

- 추상 클래스(Abstract Class)

- 인터페이스(Interface)

- 업캐스팅(Upcasting)과 다운캐스팅(Downcasting)

- 박싱(Boxing), 언박싱(UnBoxing)

- 대리자(Delegate)

 

2-2) Boxing & UnBoxing

1) Boxing과 UnBoxing

- Boxing : 값 타입을 참조타입으로 변환하는 기법

- UnBoxing : 참조타입을 값 타입으로 변환하는 기법

 

2) 박싱(Boxing)

- Boxing이란 값타입을 참조타입으로 변환하는 것을 말한다.

 

◈ Boxing의 예

int p = 123;

object o = p; //Boxing이 발생

 

 Boxing이 이루어지는 순서

- 값 타입 변수를 객체화하기 위한 메모리를 힙 역역에 생성한다. 이 공간을 Box라고 한다.

- p에 있는 값을 힙에 생성한 Box로 복사

- 참조타입 변수 o에 Box의 참조값을 할당

 

=> 값타입의 값을 object o에 담기 위해서 힙영역에 박스(Box)라는 것을 만들고, 이 박스에 값을 복사해서 넣어주면 모든 변환이 끝난다. 새로 생성된 참조값은 객체 o가 가지게 된다.

 

3) 언박싱(UnBoxing)

- UnBoxing은 Boxing된 참조타입을 다시 값 타입으로 변환하는 것을 말한다.

 

◈ UnBoxing의 예

int p = 123;

object o = p; //Boxing이 묵시적으로 이루어진다.

int j = (int)o; //UnBoxing 명시적으로 캐스팅해주어야 함

Console.WriteLine("j = " + j);

Console.WriteLine("p = " + p);

Console.WriteLine("o = " + o);

 

출력:

j = 123

p = 123

o = 123

 

◈ UnBoxing의 순서

- 해당 객체가 지정한 값타입을 Boxing 한 값인지 확인

- Boxing 된 객체라면 객체의 값을 값타입 변수에 복사한다.

- Boxing 한 메모리와 UnBoxing한 메모리 두개가 존재한다.

2-3) 구조체의 Boxing과 클래스의 형변환

 

1) 구조체의 Boxing

 

using System;

struct Point {

public int x, y;

public Point(int x, int y) {

this.x = x;

this.y = y;

}

}

class BoxingTest2 {

public static void Main() {

Point p = new Point(10, 10); // 스택 메모리 생성 - 값타입

object box = p;                  // 힙 메모리 생성 - Boxing 발생

p.x = 20;

Console.Write((Point)box).x);

//Boxing될 때 스택의 메모리가 힙영역으로 메모리가 복사되고 스택 메모리는 변환없음

}

}

출력:

10

2) 클래스의 형변환(업캐스팅)

 

using System;

class Point {

public int x, y;

public Point(int x, int y) {

this.x = x;

this.y = y;

}

}

class BoxingTest3 {

public static void Main() {

Point p = new Point(10, 10); // 힙 메모리 생성

object box = p;               // 최상위형으로 Upcasting된다. Boxing과 UnBoxing과 무관

p.x = 20;

Console.Write((Point)box).x);

}

}

출력:

20

 

=> 클래스를 이용한 객체는 참조변수이므로 당연히 p의 값은 참조값 자체이다. 그리고 object box에 이 참조값을 할당하면 box는 p의 참조값을 할당받는다. 즉, 객체의 참조할당의 법칙이 적용되는 것이지, Boxing과 UnBoxing의 변환이 아니다.

 

2-4) 인덱서 (Indexer)

 

1) 인덱서 (Indexer)

- 클래스의 객체나 구조체의 변수를 배열형식으로 이용할 수 있게 해주는 기법이다.

 

2) 인덱서를 구현하는 예제

- 문자열을 얻어내고 지정하기 위해 인덱서 사용

 

using System;

using System.Collections;

class SimpleIndexer {

ArrayList lname = new ArrayList();

public object this[int index] {

get {

if (index > -1 & index < lname.Count) { //범위내에 있는것

return lname[index];

} else {

return null;

}

}

set {

if (index > -1 & index < lname.Count) { // 범위내에 있는 것은 변경됨

lname[index] = value;

} else if (index == lname.Count) { //순서대로 하나씩 추가하면 됨

lname.Add(value);

} else {

Console.WriteLine("sid[" + index + "] : 입력범위 초과 에러!!");

}

}

}

}

class IndexerTest {

public static void Main() {

SimpleIndexer sid = new SimpleIndexer();

sid[0] = "hong";

sid[1] = "kim";

sid[2] = "sung";

 

Console.WriteLine(sid[0]);

Console.WriteLIne(sid[1]);

Console.WriteLine(sid[2]);

sid[10] = "park"; // 범위초과

}

}

출력;

hong

kim

sung

sid[10] : 입력범위 초과 에러!!

 

2-5) 추상 클래스 (Abstract Class)

 

1) 추상 클래스가 되는 방법

- 몸체없는 함수를 하나라도 포함하고 있는 클래스

abstract class Sample1{

public abstract void F();

}
- 몸체없는 함수를 포함하고 있지 않더라도 클래스를 선언할 때 abstract 키워드를 포함하고 있는 경우

abstract class Sample2{

public void G() {}

}

 

2) 추상함수의 선언 형태

- public abstract void F();

 

3) 추상 클래스의 특징

- 추상 클래스는 객체(인스턴스)를 생성할 수 없다.

- 추상 함수는 자동으로 가상함수가 된다. (추상 함수는 virtual 키워드를 사용하지 않지만 자동으로 virtual이 된다.)

 

 

2-6) 추상 함수 (Abstract Method)

 

1) 추상함수(Abstract Method)

- 몸체가 없는 함수

- 프로토타입만 가지고 있음

 

2) 추상 클래스를 상속받으면 추상클래스에서 선언한 추상함수를 모두 재정의 해야한다.

 

2-7) 인터페이스

 

1) 인터페이스의 구성요소를 보여주는 예

public delegate void StringListEvent(IStringList sender);

public interface IStringList {

void Add(String s); //함수

int Count {get; set; } //속성

event StringListEvent Changed; //이벤트

string this[int index] { get; set; } //인덱서

}

 

2) 인터페이스의 특징1

- 인터페이스 내의 멤버는 모두 몸체가 없다.

- 인터페이스의 멤버는 디폴트로 전부 public이다.

- 내부에 필드를 가질 수 없다.

- 멤버에 어떠한 접근자, 한정자도 붙이지 않는다.

 

3) 인터페이스의 특징2

- 인터페이스끼리 상속하면 더 큰 인터페이스가 된다.

- 인터페이스는 구현을 목적으로 한다.

 

◈ 클래스의 상속과 인터페이스를 동시에 상속하는 예

 

interface IA {

void SayA();

}

interface IB {

void SayB();

}

abstract class Top{

public abstract void SayTop();

}

class TopTest : Top, IA, IB {

public void SayA(){}

public void SayB() [}

public override void Saytop() {}

}

 

4) 인터페이스에서의 오버라이딩

 

using System;

interface IMyInterface {

void IMethod();

}

class MyClass : IMyInterface {

public void IMethod() {

Console.WriteLine("인터페이스의 함수를 구현");

}

public static void Main() {

MyClass mc = new MyClass();

mc.IMethod();

IMyInterface imc = mc;

imc.IMethod();

}

}

출력:

인터페이스의 함수를 구현

인터페이스의 함수를 구현

 

=> 추상클래스와 인터페이스의 추상 함수는 모두 가상(virtual) 함수의 성질을 가지고 있다. 추상 클래스 내의 추상 함수를 재정의 할 때에는 override 키워드를 사용해서 함수를 재정의하지만, 인터페이스 내의 추상 함수를 재정의 할때는 override 키워드를 사용하지 않는다.

 

 

5) 인터페이스 내의 속성 구현

 

interface IMyInterface {

int IProperty {

get;

get;

}

}

class ImplementsClass : IMyInterface {

private int iProperty;

public int IProperty {

get {

return iProperty;

}

set {

iProperty = value;

}

}

}

ImplementsClass ic = new ImplementsClass();

IMyInterface imi = ic;

imi.iProperty = 1000; //set

Colsole.WriteLine("Interface의 Property : " + imi.IProperty); //get

 

출력:

Interface의 Property : 1000

 

6) 인터페이스 내의 인덱서 구현

 

using System;

using System.Collections;

public interface SimpleInterface{

object this[int index] { get; set; } // 인덱서

}

public class SimpleIndexer : SimpleInterface {

ArrayList lname = new ArrayList();

public object this[int index] {

get {

if (index > -1 & index < lname.Count) { //범위내에 있는것

return lname[index];

} else {

return null;

}

}

set {

if (index > -1 & index < lname.Count) { // 범위내에 있는 것은 변경됨

lname[index] = value;

} else if (index == lname.Count) { //순서대로 하나씩 추가하면 됨

lname.Add(value);

} else {

Console.WriteLine("sid[" + index + "] : 입력범위 초과 에러!!");

}

}

}

}

class InterfaceIndexerTest{

public static void Main() {

SimpleIndexer sid = new SimpleIndexer();

sid[0] = "hong";

sid[1] = "kim";

sid[2] = "sung";

 

Console.WriteLine(sid[0]);

Console.WriteLIne(sid[1]);

Console.WriteLine(sid[2]);

sid[10] = "park"; // 범위초과

}

}

출력:

hong

kim

sung

sid[0] : 입력범위 초과 에러!!

 

7) 인터페이스의 명시적 구현

 

interface InterA {

void a();

}

interface InterB {

void a();

void b();

}

class Test : InterA, InterB {

public InterA.a(){

Console.WriteLine("InterA_a");

}

public InterB.a() {

Console.WriteLine("InterB_a"); 

}

public void b() {

       Console.WriteLine("InterB_b");

}

}

 

2-8) Delegate

 

1) Delegate

- 함수의 대리자

- 함수보다 효율적으로 사용하기 위하여 특정 함수 자체를 캡슐화할 수 있게 만들어주는 방법

 

2) Delegate 구현 예

 

using System;

//Delegate 선언

delegate void SimpleDelegate1();

delegate void SimpleDelegate2(int i);

class AType {

public void F1() {

System.Console.WriteLine("AType.F1");

}

public void F2(int x) {

System.Console.WriteLine("AType.F2 x=" + x);

}

}

class DeleTest {

public static void Main() {

AType atype = new AType();

//Delegate 객체 선언

SimpleDelegate1 s1 = new SimpleDelegate1(atype.F1);

SimpleDelegate2 s2 = new SimpleDelegate(atype.f2);

s1();

s2(1000);

}

}

출력:

AType.F1

AType.F2 x=1000

 

=> 하나의 클래스에서 다른 것은 필요없고 단지 특정 객체의 함수에만 관심이 있다고 해도, 해당 객체를 생성하여 그 객체의 모든 자원을 사용해야한다. 하지만 Delegate을 쓰면 하나의 함수를 빼올 수 있다.

 

=> C#에서 스레드를 사용하는 것이 위의 예와 비슷하다. C#에서 사용되는 모든 스레드는 함수를 이용해서 스레드를 시작하면 작업이 수행된다. 10개의 함수가 있다고 가정하자. 그리고 10개의 스레드를 만들고 함수를 스레드에 하나씩 넣어주고 실행하라고 명령을 내리면 10개의 스레드가 동시에 작업이 시작될 것이다. 스레드를 만들 때 함수를 넣어주어야 하는데 이 때 Delegate를 사용한다.

 

※ 스레드에서 Delegate를 사용하는 예

Top t = new Top(); // Top 클래스에 say()함수가 있다고 가정

Thread thread = new Thread(new ThreadStart(t.say));

thread.Start();

-> 여기서 ThreadStart가 Delegate이다.

 

 

'프로그래밍 > C#' 카테고리의 다른 글

C#으로 오라클접속  (0) 2012.08.29
C#으로 MySql 접속  (0) 2012.08.28
C#으로 Active Directory 접근  (0) 2012.08.28
C#의 기본문법  (0) 2012.05.08
Posted by 초코송송이
l

1. C#의 기본문법

1). 데이터 타입

C#의 데이터 타입들은 System.Object에서 파생된 System.Type 에서부터 상속된다. System.Object는 모든 데이터 타입의 부모이고, 어떠한 데이터 타입으로도 변환이 가능하다.

타 입

실제이름

범위

sbyte

System.SByte

-128 ~ 127

byte

System.Byte

0 ~ 255

char

System.Char

하나의 유니코드 문자. U+0000 ~ U+FFFF

short

System.Int16

-32,768 ~ 32,767

ushort

System.UInt16

0 ~ 65,535

int

System.Int32

-2,147,483,648 ~ 2,147,483,647

uint

System.UInt32

0 ~ 4,294,967,295

long

System.Int64

-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

ulong

System.UInt64

0 ~ 18,446,744,073,709,551,615


타 입

실제이름

정밀도

범 위

float

System.Single

7개의 자릿수

±1.5 ×10~45 ~ ±3.4 × 1038

Double

System.Double

15~16개의 자릿수

±5.0 ×10~324 ~ ±1.7 × 10308

Decimal

System.Decimal

28~29개의 자릿수

1.0 ×10~28 ~ 7.9× 1028

타 입

실제이름

특 징

Object

System.Object

모든 타입의 최상위 부모 클래스. C#에서 모든 객체들은 이 Object 클래스로부터 상속받는다.

String

System.String

문자열을 나타내는 타입이다.

Bool

System.Boolean

Boolean 값이며 참(true) 또는 거짓(false)를 나타낸다.

 

2). 선언의 간략 예

1) 변수선언의 간단 예

int x = 10;

System.Int32 x = 10;

int x, y, z;

string str = "문자열";

※ Delphi와 다른 변수이름 규칙: 대소문자를 가림

2) 구조체 선언

struct Person{

int num;

int age;

double height;

float weight;

}

구조체 변수선언과 값 할당

Person sister;

sister.num = 1000;

sister.age = 15;

sister.height = 165.3D;

sister.weight = 51.0F;

3) 열거형 선언

enum SignFlag {black, yello, green, blue, red};

=> black, yello, green, blue, red는 상수이며, 자동으로 0, 1, 2, 3, 4의 값이 할당된다.

SignFlag s1;

s1 = SignFlag.black;

Console.WriteLine("{0}={1}", s1, (int)s1);

s1 = SignFlag.blue;

Console.WriteLine("{0}={1}", s1, (int)s1);

==> 결과

black=0

blue=3

값을 지정 시: enum SignFlag {black, yello=3, green, blue=7, red};

4) 클래스 선언

class Top{

...

※ 타입캐스팅

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        a = (int)x;  // cast double to int
        System.Console.WriteLine(a);
    }
}

출력: 1234

 

3). 연산자의 종류

1) 산술연산자

기본 산술연산자: +, -, *, /, %

산술복합연산자: +=, -=, *=, /=

2) 증감/감소 연산자

++x, x++, --y, y--

4) 관계 연산자

==, >, <, <=, >=, !=

5) 논리 연산자

&(AND), |(OR), ^(Exclusive OR), ~(NOT)

&&(Short-Circuit ADN 연산자): 두개의 피연산자 중 첫번째 값이 거짓이면 무조건 거짓이 된다.

||(Short-Circuit OR 연산자): 두개의 피연산자 중 첫번째 값이 참이면 무조건 참이다.

예)

if(a>10 & b>10) {

Consol.WriteLine("AND연산자");

}

if(a>10 && b>10) {

Consol.WriteLine("Short Circuit AND연산자");

}

6) 비트 연산자

&(비트 논리곱 AND), |(비트 논리합 OR), ^(배타적 논리합 XOR), ~ (1의 보수NOT), >>(우측 쉬프트), <<(좌측 쉬프트)

 

4). 제어문 

제어문들은 기본적으로 C문법과 동일

1) if-else문, if-else if, else문

if(불형식의 표현){

참이면 실행할 문장;

} else {

거짓이면 실행할 문장;

}

2) switch case문

int btn;

btn = 2;

switch(btn) {

case 1;

btn이 1일 경우;

break;

case 2:

..

break;

case 3:

...

break;

default:

break;

}

--------------------------------------

int n = 1;
switch (n) {
    case 1:
    case 2:
    case 3:
        Console.WriteLine("1,2,3입니다");
        break;
    default:
        break;
}

3) while문, do-while문

while(조건식) {
      ...
}

--------------------------------

int i = 0;

do{

     Console.WriteLine(i);

     i++;

} while (i > 2);

4) for문

for (int i = 1; i <= 5; i++){

   Console.WriteLine(i);

}

5) foreach 문

int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };

foreach (int i in numbers){

   System.Console.WriteLine(i);

}

//다차원 배열 예 

int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
foreach (int i in numbers2D) {
    System.Console.WriteLine("{0} ", i);
}

 

5). 분기문

break, continue

 

 

2. C#의 클래스

 

1). 클래스

 

1) 클래스 만들기와 사용의 간단한 예

using System;

 

public class MethodTest {

public int a;

public int b;

public int Sum(int x, int y) {

return x + y;

}

}

public class MethodMain() {

public static void Main() {

int s;

MethodTest test = new MethodTest();

test.a = 1000;

test.b = 2000;

s = test.Sum(3, 5);

Console.WriteLine("변수 a는 " + test.a);

     Console.WriteLine("변수 b는 " + test.b);

     Console.WriteLine("Sum메서드 결과는 " + test.Sum(3, 5));

     Console.WriteLine("또다른 결과는  " + s);

}

}  

출력:

변수 a는 1000

변수 b는 2000

Sum메서드 결과는 8

또다른 결과는 8

 

2) 접근 지정자

private, protected, public

 

3) 속성(Property)

- 멤버 필드에 값을 할당하는 방법

- Set과 Get 형식의 함수를 일반화한 형태

- 스마트 필드(Smart Field)라고도 함

 

using System; 

public class Tes{

private string name; //소문자

public string Name { //대문자

get {

return name;

}

set {

name = value + " 님 반갑습니다.";

}

}

}

 

2). C#에서 구조체와 클래스의 차이점 

 

1) 구조체와 클래스의 유사점

- 클래스와 구조체는 데이터 타입 생성기이다.

 

2) 구조체와 클래스의 차이점

- 구조체는 값(Value Type)이며 클래스는 참조타입(Reference Type)이다.

 

◈ 구조체를 사용하는 이유

- 구조체는 직접적으로 메모리에 접근하기 때문에 참조의 낭비를 막을 수 있다.

 

◈ 구조체의 특징

- 구조체는 상속할 수 없으며 또한 상속해 줄 수 도 없다.

- 생성자를 중복해서 만들수 있지만 디폴트 생성자만큼은 재정의 해서 사용할 수 없다.

- (이유)값타입의 변수를 선언함과 동시에 메모리에 생성된다.

 

※ 구조체 테스트

using System;

struct Person {
    public int age;
    public long height;
    public float weight;
    public Person(int a, long h, float w) {
        age = a;
        height = h;
        weight = w;
    }
}

 

public class StructTest {
    public static void Main() {

        Person sister;
        sister.age = 13;
        sister.height = 170L;
        sister.weight = 55F;
        Console.WriteLine("sister : {0}-{1}-{2}", sister.age, sister.height, sister.weight);

 

        Person brother = new Person();//디폴트 생성자
        Console.WriteLine("brother : {0}-{1}-{2}", brother.age, brother.height, brother.weight);

       

        Person mother = new Person(40, 160L, 60F); //초기값을 할당할 수 있는 값타입의 구조체
        Console.WriteLine("mother : {0}-{1}-{2}", mother.age, mother.height, mother.weight);

       

        Person twins = sister; // 값 복사
        Console.WriteLine("twins : {0}-{1}-{2}", twins.age, twins.height, twins.weight);

}

}

 

출력:

sister : 13-170-55

brother : 0-0-0

mother : 40-160-60

twins : 13-170-55

 

==> sister와 twins은 sister를 twins에 통째로 복사된 것

그리고, brother와 mother은 new를 사용하였지만, new를 썼다고 무조건 참조타입은 아니며 값타입으로 생성된 것이다. 구조체의 초기값을 할당할 방법을 제공하기 위해 new 키워드를 사용하였지만, 값타입인 것은 변함없다.

 

 

3). Call By xxx

 

1) 값에 의한 전달 (Call By Value)

-------------------------

int a = 3;

int b = 5;

int c;

c = Sum(a, b);

-------------------------

int Sum(int x, int y) {

return x + y;

}

-------------------------

 

2) ref에 의한 참조 (Call By Reference)

 

using System;

class TestRef {

static void CallByRef(ref int x) {

x = 10000;

}

public static void Main() {

int x1 = 10; //초기화 하지 않으면 에러발생

CallByRef(ref x1);

Console.WriteLine("Call-By-Reference: {0}", x1);

}

}

출력:

Call-By-Reference: 10000

 

◈ ref 키워드

- 참조에 의한 전달을 할 때 사용하는 키워드

- 참조로 값을 넘길 때 참조할 대상은 반드시 초기화 되어야 한다.

 

3) out에 의한 참조(Call By Reference)

 

using System;

class TestRef {

static void CallByRef(out int x) {

x = 10000;

}

public static void Main() {

int x1; //초기화 하지 않음

CallByRef(out x1);

Console.WriteLine("Call-By-Out: {0}", x1);

}

}

출력:

Call-By-Out: 10000

 

◈ out 키워드

- 참조에 의한 전달을 할 때 사용하는 키워드

- 참조로 값을 넘길때 참조할 대상을 초기화 할 필요는 없다.

 

◈ out 키워드를 사용하는 경우

- 함수로부터 값을 얻어낼 때 주로 사용한다. 그렇기 때문에 초기화를 할 필요가 없는 것이다.

 

 

3. C#프로그램 시작하기

 

3-1) C# Hello World 분석

 

1) Hello World 프로그램 구성

 

using System;

namespace org.jabook {

public class HelloWorld {

public static void Main() { // 프로그램 실행은 하나의 Main()에 포함해야한다.

Console.WriteLine("Hello World!");

}

}

}

=> HelloWorld.cs로 저장

 

==> C# 프로그램에서 컴파일을 통해서 만들 수 있는 파일은 exe나 dll 형태의 파일이다. exe 파일은 프로그램의 진입점을 포함하고 있는 형태이며, dll 파일은 진입점을 포함하지 않는 순수한 라이브러리 형태이다. 진입점이 있다는 것은 Main()함수를 포함하고 있다는 의미이다.

 

※ C# 컴파일러로 컴파일하기

Visual Studio 명령프롬프트에서 (VS설치 시)

c:\>csc HelloWorld.cs

HelloWorld.exe가 생성됨 

 

2) 네임스페이스와 어셈블리

 

◈ 어셈브리(Assembly)

: 컴파일한 결과 파일(중간언어 형태로 되어 있음)

 

◈ 네임스페이스

: 어셈블리 내에서 각각의 클래스들을 구분하는 기준이 네임스페이스(Namespace)이다. 다시 말해, 어셈블리 내에는 많은 클래스들이 존재할 수 있으며, 이들 클래스를 구분하는 기준이다.

 

namespace aaa{

namespace bbb {

namespace ccc {

public class Person {

public int age;

public long height;

public float weight;

}

}

}

}

 

※ C# 컴파일러로 컴파일하기

csc /target:library /out:Person.dll Person.cs

 

3) 네임스페이스 사용하기

 

◈ 라이브러리 형태의 어셈블리(Assembly)를 사용하기 위한 절차

- Person.dll의 물리적인 위치를 명시한다. (콘솔창에서 컴파일할 때)

- 코드 내에서 Person.dll 내부에서 사용하고자 하는 네임스페이스를 using한다. (코드 내에서 작업)

 

◈ 라이브러리 생성(C#컴파일러)

- csc /target:library /out:Person.dll Person.cs

 

◈ 라이브러리 물리적 사용

- csc /reference:Person.dll /out:PersonFinal.exe PersonTest.cs

- Person.dll이 현재 디렉터리에 있기 때문에 /reference:Person.dll을 사용

- Person.dll이 다른 위치에 있다면 전체 경로 명시

 

◈ 라이브러리의 논리적 사용

  using System;

  using aaa.bbb.ccc; //사용하고자하는 네이스페이스 명시

  public class personTest {

      ...

  }

 

4) Main() 함수

 

C#에서 실행파일이면서 Main() 함수가 없다면 프로그램은 컴파일 되지 않고, 프로그램의 진입점이 없다는 에러가 발생한다.

만약, Main() 함수가 없는 라이브러리 형태의 어셈블리를 만든다면 반드시 컴파일 옵션인 /target:library를 명시해야한다.

 

◈ C#에서 Main() 함수의 형식

1. public static void Main() { .. }

2. public static void Main(string[] args) { .. }

3. public static int Main() { ... return 0; }

4. public static int Main(string[] args) { ... return 0; }

 

◈ Main() 함수의 특징

- 프로그램의 시작점이다.

- Main() 함수가 끝나면 프로그램은 종료한다.

- Main() 함수는 반드시 static으로 선언해야 한다.

- Main() 함수에서 객체를 생성하거나 다른 함수를 호출할 수 있다.

- 명령 프롬프트 상의 매개변수를 읽기 위해서 string 배열을 사용한다.

 

5) static 키워드

모든 클래스에서 공유하기 위한 멤버를 선언하기 위해 사용한다. 객체가 아무리 많이 생성되더라도 스태틱 멤버로 선언되어 있으면 프로그램 내에서 단하나의 메모리만 생성된다. 모든 객체에서 공통으로 사용하는 전역변수의 개념으로 사용할 때 이 스태틱을 사용한다.

 

6) Console.WriteLine() 함수

- System 네임스페이스의 클래스

- WriteLine() 함수는 Colsole 클래스의 스태틱 멤버함수이며 화면에 표준출력을 처리하는 함수

 

예)

Console.WriteLine("a: {0}, b: {1}, a-b: {2}", a, b, a-b);

 

 

3-2) 스태틱 메모리, 함수, 생성자

 

1) 스태틱 메모리

 

◈ 스태틱 사용의 예

public class StaticAccess {

public static in sint = 0;

public int nint = 0;

public static void Main() {

StaticAccess.sint = 3333;

StaticAccess sa = new StaticAccess();

sa.nint = 1000;

Console.WriteLine("static직접접근: " + StaticAccess.sint);

Console.WriteLine("일반멤버 필드접근: " + sa.nint);

}

}

 

◈ 스태틱 메모리에 접근하는 방법

- 클래스의 이름으로 접근한다. (StaticAccess.sint)

 

◈ 스태틱 메모리 생성시기

- 객체를 생성하기 이전에 스태틱의 메모리는 생성된다.

 

2) 스태틱 함수

 

◈ 스태틱 멤버함수

- 스태틱 멤버함수는 클래스의 이름으로 접근 가능하다.

- public static 함수만 접근 가능하다.

 

◈ 스태틱 멤버 함수에서 주의할 점

- 스태틱 함수를 이용하여 일반 멤버 필드에 접근 불가

- 일반 멤버 필드는 객체 생성 후에 존재하기 때문에 스태틱 함수에서 접근 불가

 

◈ 스태틱 함수의 사용

 

public class StatiMethodAccess {

private static int sint = 100;

public int nint = 0;

public static void SetStaticInt(int x) {

sint = x;

}

public static int GetStaticInt() {

return sint;

}

public static void Main() {

StaticMethodAccess.SetStaticInt(33333);

int s = StaticMethodAccess.GetStaticInt();

Console.WriteLine("static값은 : " + s);

}

}

 

3) 스태틱 생성자

 

◈ 스태틱 생성자

- 스태틱 생성자는 스태틱 멤버 필드의 메모리가 생성된 직후 호출되는 스태틱 전용의 생성자 함수이다.

 

◈ 스태틱 생성자의 특징

- 접근제어를 사용할 수 없음

- 매개변수를 가질 수 없음 : 스태틱에 접근하는 순간 스태틱 생성자는 자동으로 호출되므로 매개변수를 넣어줄 방법이 없다.

 

 

◈ 스태틱 생성자의 사용

 

class StaticConst {

public static int sInt = 0;

static StaticConst() { //스태틱 생성자

sInt = 10;

Console.Write("sInt = " + sInt + " : static 생성자!!");

}

public StaticConst() { //디폴트 생성자

//

}

public static void InitSint(int a) {

sInt = a;

}

}

class StaticConstTest {

public static void Main() {

int a = StaticConst.sInt;

}

}

 

==> 스태틱 멤버 필드들은 클래스가 생성되기 전에 메모리가 생성된다. 그렇다고 한다면 스태틱의 멤버의 값을 초기화할 수 있는 곳은 선언하는 순간에 할당할 수 밖에 없다. 딱히 다른곳에서 할데가 없다 이 방법 이외에 스태틱 생성자라는 것을 이용할 수도 있다.

 

※ Main() 함수가 static 함수인 이유

- 실행 클래스의 객체가 생성되기 이전에 CLR이 Main() 함수에 접근해야 하기 때문이다.

 

 

3-3) const, unsafe

 

1) const 상수 

 

◈ const 키워드

- 상수를 선언하는 키워드

 

◈ const 상수 선언하기의 예

- public const int SALLERY = 7070;

 

◈ const 상수의 특징

- const는 자동으로 static이 된다.

- const로 선언한 변수는 반드시 초기화 되어야 한다.

 

2) readonly 상수

 

 ◈ readonly 상수의 특징

- 반드시 초기화할 필요없다.

- 생성자에서 딱 한번 값을 할당할 수 있다.

- static 키워드를 사용하면 스태틱 상수가 되고 사용하지 않으면 일반 상수가 된다.

 

◈ static readonly

- static readonly 일 경우 스태틱 생성자에서 초기화할 수 있다.

- static readonly 일 경우 클래스의 이름으로 접근가능

 

◈ 일반 readonly

- 일반 readonly 일 경우 생성자에서 초기화 할 수 있다.

- 일반 readonly 일 경우 객체의 이름으로 접근가능

 

◈ readonly의 사용

using System;

public class ReadonlyTest {    

public readonly static int STATIC_READONLY = 1;

public readonly int NORMAL_READONLY= 1;

 

static ReadonlyTest() { //static 생성자

STATIC_READONLY = 100;

}

public ReadonlyTest() {//일반 생성자

NORMAL_READONLY = 100000;

}

public static void Main() { //

Console.Write("STATIC_READONLY = " + ReadonlyTest.STATIC_READON

ReadonlyTest rt1 = new ReadonlyTest();

Conesole.Write("NORMAL_READONLY" + rt1.NORMAL_READNLY);

}

}

 

3) 가비지 콜렉터와 메모리

 

◈ c++에서 메모리 관리

- new 를 사용해서 메모리르 생성했으면 반드시 사용자가 직접 delete를 사용해서 메모리를 제거해 주어야한다.

 

◈ 가비지 콜렉터

- C#의 메모리 관리자 역할을 한다.

 

◈ 가비지 콜렉터가 하는 일

- 더이상 사용하지 않는 메모리나 불필요한 메모리를 제거한다.

- 메모리가 부족하면 메모리의 조각 모음을 한다.

 

◈ 가비지 콜렉터의 관리 대상

- 힙에 생성되는 객체의 메모리

 

=> C#에서는 new는 사용하지만 delete는 사용하지 않는다. 가비지 콜렉터를 지원해주기 때문이다. 가비지 콜렉터는 CLR 내에서 동작하면서 메모리의 청소가 필요하다고 생각될 때 시스템에 의해서 구동되는 메모리 청소부와 같은 역할을 담당한다.

 

4) unsafe 코드

 

◈ unsafe code

 - C#에서 포인터를 사용하면 unsafe code가 된다.

- CLR이 메모리를 전자동으로 관리해 주는데 사용자가 직접 메모리를 건드는 것은 안전하지 못하기 때문에 unsafe code라고 한다.

 

◈ unsafe code 컴파일 옵션

- unsafe code를 컴파일할 때 컴파일 옵션으로 /unsafe를 사용해서 컴파일해야 한다. 

 

◈ unsafe code 사용

- C#에서 포인터(*)를 사용하기 위해서 unsafe 키워드를 이용해서 사용할 수 있다.

 

using System;

class UnsafeTest {

unsafe static void CallByPoint(int* x) {

*x = 1000;

}

public static void Main() {

int x1 = 10;

unsafe {

CallByPoint(&x1);

}

Console.WriteLine("Call-By-Point: {0}", x1);

}

}

 

4) fixed 키워드를 이용한 메모리 고정

 

◈ fixed 키워드

- CLR에 의해 해당 메모리의 포인터를 이동시키지 못하도록 하는 키워드

- unsafe code 내에서만 사용할 수 있다.

- CLR이 메모리를 이동하지 않는다는 것이 보장된다.

 

◈ fixed의 사용 예

 

using System;

class FixedTest

{

unsafe static void ArrayCopy(byte[] source, byte[] target) {

fixed(byte* s = source, t = target) {

for( int  i = 0 ; i < source.Lengh ; i++ )

                        *(t+i) = *(s+i);

              }

        }

public static void Main() {

byte[] sample = {5, 6, 4, 6, 3, 4, 100};

byte[] copyed = new byte[7];

ArrayCopy(sample, copyed);

foreach(byte temp in copyed)

Console.Write(temp + "\t");

}

}

결과:

5    6    4    6    3    4    100

 

'프로그래밍 > C#' 카테고리의 다른 글

C#으로 오라클접속  (0) 2012.08.29
C#으로 MySql 접속  (0) 2012.08.28
C#으로 Active Directory 접근  (0) 2012.08.28
C#의 객체지향  (0) 2012.05.10
Posted by 초코송송이
l