'C#'에 해당되는 글 20건

  1. 2009.12.03 C# 프로그래밍 도구
  2. 2009.08.25 C# and Excel (reading) (1)
  3. 2009.08.12 C# 쓰레딩 [멀티쓰레딩]
  4. 2009.08.12 C# 쓰레딩 [시작과 종료]
  5. 2009.08.06 연산자 오버로딩 - 인덱스
  6. 2009.08.06 C#에서의 데이터형
  7. 2009.08.05 닷넷 3.5를 이용한 디자인 패턴의 구현 (4)
  8. 2008.09.04 C#으로 이미지 리사이즈/조작 시 부드럽게 렌더링 하기
  9. 2008.08.28 ASP.NET 2개 폼 사용하는 꽁수
  10. 2008.08.28 하나의 클래스를 통째로 넘기는 방법 ( a.aspx.cs -> b.aspx.cs )
2009.12.03 08:33

C# 프로그래밍 도구

C# 프로그래밍 도구

C# 팀이 웹에서 다른 CLI 구현, 멋진 개체 브라우저, IDE 트릭, 추가 기능, Obfuscator를 비롯하여 보다 신속한 작업 수행을 지원하는 기타 유용한 도구와 유틸리티를 찾았습니다.

코드 생성 도구를 포함하여 유용한 도구, 프레임워크 및 클래스 라이브러리에 대한 추가 링크를 보려면 클래스 및 라이브러리 페이지를 확인하십시오.


주요 도구

Microsoft® .NET 응용 프로그램을 위한 IMSL™ C# Numerical Library

C# Numerical Library는 30년 전부터 시작된 선도적인 수학 및 통계 라이브러리입니다.

Extreme Optimization Mathematics Library for .NET
Extreme Optimization Mathematics Library for .NET에는 복소수, 곡선, 방정식, 수치 적분, 수치 미분, 벡터, 행렬 및 다양한 특수 함수를 위한 클래스가 포함되어 있습니다.
devAdvantage : Visual Studio .NET을 위한 C# 소스 코드 분석기

코드에서 초기에 문제를 확인하면 개발 과정 후반의 코드 검토, 테스트 및 버그 수정에 소요되는 시간을 줄여 개발 주기를 단축하고 프로젝트 비용을 낮출 수 있습니다. devAdvantage는 C# 소스 코드에 버그 및 문제가 있는지 분석하여 코드 검토를 자동화하는 Microsoft Visual Studio .NET 추가 기능입니다.

라이브러리 및 기타 자료

C# 컴파일러 및 프레임워크

Obfuscator

디컴파일러

프로파일러/최적화 도구

리팩터링

개체 브라우저

편집기

IDE(개발 환경)

빌드 도구

표준 검증 도구

테스트

설명서

데이터베이스

정규식

그래픽, 게임 및 그리기


출처 : http://msdn.microsoft.com/ko-kr/vcsharp/aa336818.aspx
신고

'소프트웨어 > C# & ASP.NET' 카테고리의 다른 글

Data Access Application Block  (0) 2009.12.09
문자열 비교 - 팁  (0) 2009.12.09
C# 프로그래밍 도구  (0) 2009.12.03
Windows Mobile in C# 강좌 Lab 2 - GPS 사용법(2)  (0) 2009.11.26
c# 개념잡기 - Generic  (0) 2009.11.25
get/set 메소드와 public 멤버변수  (0) 2009.11.25
Trackback 3 Comment 0
2009.08.25 08:34

C# and Excel (reading)

이전 포스트 였던 C#을 이용한 엑셀(쓰기) C# and Excel (writing) 에서 번 포스팅 에서는 엑셀(읽기)를 해보겠습니다.

이전 포스트와 같은 환경 Microsoft Visual Studio 2008 + Microsoft Office Excel 2007 이며 처음 참조추가 하는 부분은 같습니다. 혹시 이 글을 처음 보신다면 이전 글을 먼저 확인해 보세요^^.

 

역시 이번 포스팅도 상당히 간단하게 끝납니다. 역시 사용법을 몰랐을 뿐이죠…

01.string conStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\sample.xlsx;Extended Properties=\"Excel 12.0;HDR=YES;\"";
02.OleDbConnection excelConnection = new OleDbConnection(conStr);
03.excelConnection.Open();
04. 
05.string strSQL = "SELECT * FROM [Sheet1$]";
06.OleDbCommand dbCommand = new OleDbCommand(strSQL, excelConnection);
07.OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand);
08. 
09.DataTable dTable = new DataTable();
10.dataAdapter.Fill(dTable);
11. 
12.dataGridView_excel_data.DataSource = dTable;
13. 
14.// dispose used objects
15.dTable.Dispose();
16.dataAdapter.Dispose();
17.dbCommand.Dispose();
18. 
19.excelConnection.Close();
20.excelConnection.Dispose();

1번째 줄에서는

Provider=Microsoft.ACE.OLEDB.12.0; 오피스 버전에 영향을 받습니다.
Data Source=c:\sample.xlsx; 파일경로 입니다.
Extended Properties="Excel 12.0;HDR=YES"; 엑셀을 가르키며, HDR엑셀 데이터의 첫번째 row 를 columnname 으로 지정할지 하지 않을지 결정하게됩니다. YES 는 지정입니다.

2~11번째는 OleDb 커넥,명령 등입니다.

12번째 줄은 폼에서 생성한 DataGridView에 DataSource로 dTable 을 지정하는 부분입니다. 이부분을 지나게 되면 폼에서 DataGridView에 내용이 채워지게 됩니다.

14~20번째 는 OleDb 커넥 종료와 Objects 들을 Dispose 하게 됩니다.

 

1번째 줄의 HDR=YES or NO 를 통해 어떻게 바뀌는지 확인해 보겠습니다.

우선 Excel File 윈 원본 데이터를 먼저 보겠습니다.

 

HDR=YES 로 설정한 경우는 아래와 같이 DataGridView 에 컬럼 제목으로 들어가게 됩니다.

 

반면 HDR=NO 로 설정하게 되면 컬럼명은 기본 셋팅값으로 바뀌고 원하던 바로 되지 않고 제목까지 데이터 쪽으로 내려가 버립니다.

 

이제부터는 원하는 부분을 읽어보도록 하겠습니다. (DataGridView 내용에서)

 

1.//DataGridView 에서 Rows 를 얻어옵니다.
2.DataGridViewRowCollection rowCollection = dataGridView_excel_data.Rows;
3.string getStr = rowCollection[1].Cells[3].Value.ToString();

 

row는 열을 가리키며 가로줄 입니다. 1줄에서 데이터그리드로 부터 Rows 를 얻어와 컬렉션에 집어 넣습니다. 이렇게 되면 rowCollection 을 통해 내용을 얻어 올 수 있습니다. 그리하여 다음줄에 인덱스연산을 통해 원하는 부분의 Value 를 얻어 올 수 있습니다.

 

어때요 참 쉽죠?ㅋ

 

또 한번의 간단한 포스팅이 끝났네요^^ㅎ 다음 포스팅에서는 인쇄 작업을 해보겠습니다.



출처 : http://dklee.net/46

신고
Trackback 0 Comment 1
  1. BlogIcon 모세s 2010.01.15 14:42 신고 address edit & del reply

    큰 도움이 되었습니다 ^^..
    hdr이 헤더포함인데,, 이걸 모르고 왜 첫째 열이 안읽히나 고생했네요.
    감사합니다.

2009.08.12 19:20

C# 쓰레딩 [멀티쓰레딩]

지난번에 Thread를 왜 쓰레드라고 표기한지에 대해서와 단일 쓰레드의 시작과 종료에 대해 썰을 풀었다.
이번에는 멀티 쓰레드와 동기화를 함해보고 담에는 쓰레드 풀에 대해 썰을 풀어보자.

using System;
using System.Threading;

//데이터를 주고받아야 하니 Class를 하나 만들고 인터페이스도 만들어 두자.
class work{
  int a; //받을 인자값

  //인터페이스 메소드
  public work(int a){
   this.a = a;
  }
 
  //실제 일할놈
  public void runit(){
   for (int i=0; i<10; i++){
    Console.WriteLine("Thread{0} Running : {1}", a, i);
    Thread.Sleep(100);
   }
  }
}

//메인쓰레드가 있는 클래스
class Test {
  static void Main(){
   Console.WriteLine("쓰레드 시작");
   work wk1 = new work(1); //1로 지정
   work wk2 = new work(2); //2로 지정
   ThreadStart td1 = new ThreadStart(wk1.runit); //시작쓰레드 선언하고
   ThreadStart td2 = new ThreadStart(wk2.runit);
   Thread t1 = new Thread(td1); //돌릴준비하고
   Thread t2 = new Thread(td2);
   t1.Start(); //돌리자
   t2.Start();
  }
}

사용자 삽입 이미지
실행후 1번과 2번 쓰레드가 동시에 작동한다.

그런데 1번보다 2번 쓰레드가 중요하다던가 하는 상황에서는 어떻게 하면 될까?
그때는 "ThreadPriority"메소드를 사용하여 우선순위를 지정할 수 있다.

using System;
using System.Threading;
class work{
  int a;
  public work(int a){
   this.a = a;
  }
 
  public void runit(){
   for (int i=0; i<10; i++){
    Console.WriteLine("Thread{0} Running : {1}", a, i);
    Thread.Sleep(100);
   }
  }
}
class Test {
  static void Main(){
   Console.WriteLine("쓰레드 시작");
   work wk1 = new work(1);
   work wk2 = new work(2);
   ThreadStart td1 = new ThreadStart(wk1.runit);
   ThreadStart td2 = new ThreadStart(wk2.runit);
   Thread t1 = new Thread(td1);
   Thread t2 = new Thread(td2);
   t1.Priority = ThreadPriority.Lowest; //이 부분 추가됨. 1번 쓰레드 우선 순위 최하
   t2.Priority = ThreadPriority.Highest; //이 부분 추가됨. 2번 쓰레드 우선 순위 최고
   t1.Start();
   t2.Start();
  }
}

1번 쓰레드에 우선 순위를 최하로 부여하고 2번 쓰레드에는 우선 순위를 올려 보았다.
(설정은 "Highest, AboveNormal, Normal, BelowNormal, Lowest"로 5단계로 설정할 수 있다.)
사용자 삽입 이미지
본 코드가 적용되기전의 결과와는 다르게 2번 쓰레드가 먼저 생성되고 종료된다.
그러나 믿지는 말자. 인텔 계열의 CPU는 0부터 31까지의 값을 가지고 있고 이는 윈도우에서 사용하는 우선 순위나 별반 다르지 않다.

* 작업관리자에서 우선순위를 설정해 보신분들은 금방 알아볼 것이다. 다음의 그림처럼...
사용자 삽입 이미지
암튼 지맘이니까 믿지는 말자. 쓰레드의 위험성은 이처럼 결과를 예측하고 그 예측이 맞을것이라 바라는것 되겠다. 절대 하지말아야 할 주의점 이다.

이렇게 멀티로 작업을 하다보면 공통 변수로 작업해야 할때가 있다. 이때 여러개의 쓰레드가 1개의 값을 건드리다보면 변수의 값이 엉뚱하게 나오기도 한다.

using System;
using System.Threading;
class work{
  public int a;
  public void runit(){
   int tp = a + 1;
   Console.WriteLine(tp.ToString());
   Thread.Sleep(10);
   a = tp;   
  }
}
class Test {
  static void Main(){
   Console.WriteLine("쓰레드 시작");
   work wk = new work();
   Thread[] td = new Thread[5];
   for (int i=0; i<5; i++){
   td[i] = new Thread(new ThreadStart(wk.runit));
   td[i].Start();
   }
   Thread.Sleep(1000);
   Console.WriteLine("최종값:{0}",wk.a);
  } 
}

요녀석을 실행함 해보자.
사용자 삽입 이미지
결과값은 분명 5가 나와야 하지만 그렇지 않고 1로 고정이 되어버렸다.
다음과 같이 lock이란 녀석을 한번 넣어보자.
using System;
using System.Threading;
class work{
  public int a;
  public void runit(){
   lock(this){ //바로 여기
   int tp = a + 1;
   Console.WriteLine(tp.ToString());
   Thread.Sleep(10);
   a = tp;   
    }
  }
}
class Test {
  static void Main(){
   Console.WriteLine("쓰레드 시작");
   work wk = new work();
   Thread[] td = new Thread[5];
   for (int i=0; i<5; i++){
   td[i] = new Thread(new ThreadStart(wk.runit));
   td[i].Start();
   }
   Thread.Sleep(1000);
   Console.WriteLine("최종값:{0}",wk.a);
  } 
}


실행을 하면 다음과 같이 정상값으로 나온다.
사용자 삽입 이미지
lock이란것으로 동시에 호출하는 쓰레드에 대해 작업중이니 기다리라는 명령을 내릴 수 있는것이다. 그러나 기능의 다양성을 원한다면 lock보다는 "Monitor.Enter()"와 "Monitor.Exit()"를 써주기 바란다.

  public void runit(){
   Monitor.Enter(this);
   int tp = a + 1;
   Console.WriteLine(tp.ToString());
   Thread.Sleep(10);
   a = tp;   
    Monitor.Exit(this);
  }

출처 : http://www.wolfpack.pe.kr/123?category=2

신고
Trackback 0 Comment 0
2009.08.12 19:04

C# 쓰레딩 [시작과 종료]

쓰레드라고 하는것이 한때는 고수들의 전유물이었는데 요즘은 강호고수들이 많아져서인지 아무나 쓰는 기술되었다.
뭐 암튼 대충 쓰레드에 대해 정리하자는 차원에서 써둠을 밝히니 향후에 제대로 안된다고 이런거 하지말자.

1. 쓰레드 사용하기
일단 닷넷의 쓰레드는 굉장히 쓰기쉽다.
다음의 예제를 함해보자.

using System;
using System.Threading;  //쓰레드를 쓰겠다고 선언하자.

class Test {
  static void Main(){
   Console.WriteLine("카운트 0부터 49까지 세기!");
   ThreadStart th = new ThreadStart(work); //1.work메소드를 위임하자.
   Thread t = new Thread(th); //2.쓰레드생성하자.
   t.Start(); //3.시작
   Console.WriteLine("끝!");
  }
  public static void work(){
   for (int i = 0; i<50; i++){
    Console.WriteLine("Conut:{0}",i);
   }
  }
}

결과를 보면 짜잔!
사용자 삽입 이미지

* Ultraedit에서 컴파일하고 실행한 결과창임. 이렇게 하고싶으신분들은 본 블로그 잘뒤져보면 나옴.

2. 쓰레드 중지하기
쓰레드를 중지하기위해서는 2가지 방법이 있다.
- Abort()
- Join()
Abort()는 강제종료이므로 어디서 끝날지 아무도 모른다. 신도 모른다.
Join()은 쓰레드가 다 실행될때 까지 기다렸다가 종료시킨다.
다음예제를 보자

using System;
using System.Threading;

class Test {
  static void Main(){
   Console.WriteLine("카운트 0부터 1만까지 세기!");
   ThreadStart th = new ThreadStart(work);
   Thread t = new Thread(th);
   t.Start(); //시작
   t.Abort(); //강제종료
   Console.WriteLine("끝!");
  }
  public static void work(){
   for (int i = 0; i<10000; i++){
    Console.WriteLine("Conut:{0}",i);
   }
  }
}


이녀석을 실행해보면 Abort()때문에 이렇게 된다.
사용자 삽입 이미지

코드에서는 1만까지 진행하는것으로 만들어졌지만 강제종료되어 8524에서 종료되었다.
한번 더 해보자.

사용자 삽입 이미지
어쩌구리.. 이번에는 다 돌아 버렸다... ㅡㅡ;; 암튼 이런식으로 예측이 불가능한 코드가 되어버린다. 중간에 종료하는것은 왠만하면 하지말고 Join()을 사용하도록 하자.
위코드에서 다음과 같이 수정한다.
   ...전략...
   t.Start(); //시작
   t.Join(); //이전에 t.Abort()임
   Console.WriteLine("끝!");
   ...후략...

사용자 삽입 이미지
이번에는 다 돈다. (사실은 위의 이미지와 같은 이미지임.. 흐흐흐)

3. 쓰레드의 쉬게하기
이번에는 일하다가 중간에 쉬게 해보자.
using System;
using System.Threading;

class Test {
  static void Main(){
   Console.WriteLine("쓰레드 시작");
   ThreadStart th = new ThreadStart(work);
   Thread t = new Thread(th);
   t.Start();
   Console.WriteLine(t.ThreadState);
   Console.WriteLine("끝!");
  }
  public static void work(){
   Thread.Sleep(100);
  }
}


사용자 삽입 이미지
쓰레드가 시작되고 Sleep명령으로 인해 Sleep모드로 들어갔다.

명령이 주어질때까지 중지하고 싶다면 Suspend()를 사용하자. Suspended된놈을 다시 살리는 것은 Resume()이 있는데 이건 알아서 한번 만들어 보도록 하자.

결론적으로 .NET의 쓰레드(Thread)는 다음과 같은 상태값을 가진다.
(ThreadState()로 나오는 결과값이 바로 타원형안에 있는 녀석들이다.)

사용자 삽입 이미지
이 표만 잘봐두면 쓰레드 어려운것이 아니다.
일단 생성된 쓰레드는 Unstarted라는 값을 가진다. Start()라는 메소드로 Started라는 상태값을 가지게 되는 것이다. 다시말해 타원안에 있는 것은 상태값, 화살표에 있는 것이 바로 메소드 되겠다.

다음에는 멀티 쓰레드 함 해보자.

* 본 게시물에서 사용한 쓰레드라는 표현은 "Thread"의 한음표현이며 쓰레드는 스레드라고도 표기됩니다. Microsoft공식학습서 Inside C# 2nd Ed.에는 쓰레드라고 표기되어 있어 본 게시물도 쓰레드라고 표현함을 알려드립니다.


출처 : http://www.wolfpack.pe.kr/120?category=2
신고
Trackback 0 Comment 0
2009.08.06 18:18

연산자 오버로딩 - 인덱스











class Point
{
public int x;
public int y;

public Point(int x, int y)
{
this.x = x;
this.y = y;
}


public override string ToString()
{
//(x,y)값
return String.Format("({0},{1})",x,y);
}
// + 연산자 메서드
public static Point operator +(Point pt1, Point pt2)
{
return (new Point(pt1.x + pt2.x, pt1.y + pt2.y));
}

// - 연산자 메서드
public static Point operator -(Point pt1, Point pt2)
{
return (new Point(pt1.x - pt2.x, pt1.y - pt2.y));
}

}
class Class1
{
static void Main(string[] args)
{
Point pt1 = new Point(100, 100);
Point pt2 = new Point(100, 200);
Point pt3;

// Point 객체 + 연산
pt3 = pt1 + pt2;

Console.WriteLine("{0} + {1} = {2}", pt1, pt2, pt3);
}
}











인덱서란 
프로퍼티(Property)의 기본 아이디어는 클래스를 사용하는 입장에서 보았을 때 마치 필드를 직접 사용하는 것처럼 보이도록 하는 것 
실제로는 get/set 메서드가 불려져서 필드 값을 넣거나 가져온다 

   // 프로퍼티를 사용한 예
     pt.X = 100;
     int x = pt.X;


인덱서(Indexer)는 프로퍼티를 모아 놓은 배열을 사용하는 개념 
get/set 메서드를 이용하며, 여러 개의 값을 다루기 때문에 인덱스 값이 필요 

    // 비트 배열을 인덱서로 사용한 예
     Bits[0] = true;
     Bits[1] = false;


인덱서(indexer) 
일련의 데이터 값을 가질 수 있는 데이터 구조가 필요 
사용할 데이터형을 지정하고, 클래스 자체를 배열처럼 사용하기 때문에 this를 사용하고 [ ] 사이에 인덱스로 사용할 데이터형을 지정 





인덱서(indexer) 
프로퍼티와 마찬가지로 get/set 메서드가 불려지며, 특정 값을 가리키는 인덱스를 지정 









ObjList 인덱서 만들기 예제 

ArrayList 클래스를 사용해서 object 형 데이터 리스트를 다루는 인덱서를 정의해보는 예제 



ArrayList 콜렉션 클래스를 다루기 위해 Collections 네임스페이스를 추가 

 using System;
 using System.Collections;    

 ObjList 클래스를 정의하고, 멤버로 ArrayList 클래스를 추가 

 public class ObjList
{
    protected ArrayList data; // ArrayList 객체

    public ObjList() 
    {
        data = new ArrayList();
        // ArrayList 클래스는 동적으로 배열 크기를 관리하며, 
        // 내부적으로 관리하는 데이터는 object 형 
    }
}


ObjList 클래스에 다음과 같이 인덱서를 추가하고, get 메서드에서 값을 리턴하며, 인덱스가 범위를 벗어나는지 검사해서 예외 처리


public object this[ int i ]
    {
        get 
        {
            if ( i >= 0 && i < data.Count ) // 인덱스 범위 검사
            {
                return data[i];
            }
            else
                throw new IndexOutOfRangeException( "범위 벗어남" + i );
        }
        set
        {}
    }

set 메서드에서 값을 넣을 때도 마찬가지로 범위를 검사해서 범위 내에 들어있는 경우에만 값을 넣어주며, 마찬가지로 범위를 벗어나는 경우는 예외 처리 

set 
        {
            if ( i >= 0 && i < data.Count ) // 인덱스 범위 검사
            {
                data[ i ] = value; 
            }
            else
            if ( i == data.Count ) // 마지막 데이터 요소인 경우
            {
                data.Add( value ); // 데이터를 추가합니다.
            }
            else
                throw new IndexOutOfRangeException( "범위 벗어남" + i );
        }


인덱서에 여러 데이터형을 가진 값을 넣고, 값을 출력

public class Class1
{
    public static void Main()
    {
        ObjList list = new ObjList();

        list[0] = 100;
        list[1] = "apple";
        list[2] = 123.456;

        for( int i=0; i<3; i++ )
            Console.WriteLine( "[{0}] = {1}", i, list[i] );
    }
}


출처 : http://ssogarif.tistory.com/entry/%EC%97%B0%EC%82%B0%EC%9E%90-%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9-%EC%9D%B8%EB%8D%B1%EC%8A%A4
신고

'소프트웨어 > C# & ASP.NET' 카테고리의 다른 글

ASP.NET 2.0 프로젝트의 특정 폴더의 설명  (0) 2009.08.07
.NET Assembly  (0) 2009.08.07
연산자 오버로딩 - 인덱스  (0) 2009.08.06
C# 디버깅  (0) 2009.08.06
C#에서의 데이터형  (0) 2009.08.06
닷넷 3.5를 이용한 디자인 패턴의 구현 (4)  (0) 2009.08.05
Trackback 0 Comment 0
2009.08.06 08:55

C#에서의 데이터형

값형과 레퍼런스형 비교

닷넷에서
제공하는 데이터형은 변수가 어떤 값을 갖느냐에 따라 분류

(value) 형  변수가 실제 데이터 값을 직접 가지고 있는 경우

(value) 형은 스택(stack) 메모리 공간에 저장되며, 할당 연산을 했을 때 별도의 메모리 영역에 할당


레퍼런스(reference) 형 변수가 실제 데이터 값이 있는 곳을 가리키는 값을 갖는 경우 

레퍼런스(reference) 형은 (heap) 메모리 공간에 저장

할당 연산을 했을 때  메모리 공간을 가리키는 레퍼런스 변수 값 사이에서 할당이 일어남




 IntObj  r1  =  new  IntObj();



스택(Stack)데이터 값을 임시로 저장하는 메모리 영역으로, 보통 메서드의 인자, 메서드 안에 선언한 변수들이 스택 공간에 할당

(Heap)일반적인 데이터 값을 할당하는 메모리 영역으로, 변수에 바로 데이터 값이 있는 것이 아니라 new 연산

자를 사용해서 메모리를 할당하고 값을 저장


(value)


다음은 값(value) 데이터형 중에서 int 형을 사용한 예
v2에 값을 할당하는 경우 v2 값만 바뀌므로, v1 값과 v2 값이 별도의 메모리 공간을 갖고 저장되
기 때문의 이유

exam)

class Test


{

    static void Main()


    {

        int v1 = 100;


        int v2 = v1;


        Console.WriteLine( "v1 : {0} v2 : {1}", v1, v2 ); // 100, 100



        v2 = 200;


  Console.WriteLine( "v1 : {0} v2 : {1}", v1, v2 ); // 100, 200

    }


}






레퍼런스(Reference) 



int 형 멤버를 갖는 클래스를 하나 정의멤버 값을 바꾸게 되면 해당 변수뿐만


아니라 다른 변수에도 영향을 준다



r2에 값을 할당하는 경우, r1과 r2가 값이 동시에 바뀌며이유는 같은  메모리 공간


을 가리키고 있기 때



using System;


class IntObj


{


    public int val = 100;






exam)


 using System;


class IntObj


{


    public int val = 100;


}


class test


{

    static void Main()


    {


        IntObj r1 = new IntObj();


        IntObj r2 = r1;


        Console.WriteLine( "r1 : {0} r2 : {1}", r1.val, r2.val ); // 100, 100


        r2.val = 200;


        Console.WriteLine( "r1 : {0} r2 : {1}", r1.val, r2.val ); // 200, 200

    }

}




출처 : http://ssogarif.tistory.com/entry/C%EC%97%90%EC%84%9C%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%98%95

신고
Trackback 0 Comment 0
2009.08.05 08:00

닷넷 3.5를 이용한 디자인 패턴의 구현 (4)

이름에 짐작할 수 있듯이, Observer 패턴은 오브젝트의 상태를 관잘하는 데 사용된다. 이 패턴이 약간 변형된 패턴이 출판 (Publish)과 구독(Subscribe)이다 관찰 대상 오브젝트는 어떤 이벤트 혹은 이벤트들을 "출판"하고 이들을 주시하고 있던 오브젝트들(관찰자들)은 발생한 이벤트를 "구독"한다.

이것을 좀 더 단순화하기 위해, 두 패턴을 모두  Observer 패턴이라고 부를 것이다. 사실 이 두 가지 패턴의 차이는 보는 관찰 시점의 차이일 뿐이다. 쉽게 얘기해서, '당신이 나를 관찰하고 있나요? 와 내가 당신이 구독하려는 나의 이벤트를 출판하고 있나요? 의 차이와 같다. 전자는 나를 보는 관점이 타인이 시점이고 후자는 자신의 시점에서 일어나는 이벤트를 관찰하게 된다.

Observer 패턴은 오브젝트들 사이에 일대다 의존성을 갖는다. 그래서 , 하나의 오브젝트가 상태를 변경하면, 이것에의존하는 모두에게 변경 사실이 통보되고 변경에 대해 반응할 수 있는 기회를 가진다

이패턴의 기본 개념은 관찰자(Observer) 혹은 청취자(listener)라고 불리는 오브젝트들이 주제(subject)라고 불리는 관찰 대상 오브젝트에서 일어날지도 모르는 이벤트를 관찰하기 위해 등록되거나 스스로 등록하는 것이다.


Observer 패턴을 펴현한 UML 클래스 다이어그램




좀 더 확실히 하기 위해서, 실제 생활 속의 예를 들어볼 것이다. 많은 사람들이 블로그를 읽는다. 아직까지 방문해 본 적이 없다면, 지금부터 시작하면 된다. 이들 중 일부는 Slashdot의 오늘의요약 정보를 구독할지도 모른다. 이 사이트는 Observer패턴에 대해 알아야 할 것의 모든 것을 보여준다. Slashdot은 출판하고 사람들은 구독한다. 혹은 관점을 바꿔서, 사람들을 관찰하고 Slashdot은 관찰된다.


관찰의 주제




예제를 통해 알아보는 Observer 패턴


비행 출발과 항공 교통을 처리하는 약간 단순한 Observer 패턴을 적용한 프로그램을 만들어 보자. 이 예제는 패턴을 구성하는 네 가지 구성요소가 있다

주제(subject)와 관찰자(observer)는 실제로 사용하기 위해 필요한 메소드와 변수를 정의하는 인터페이스이고 이를 구현한 것이 실제주제(Concrete subject)와 실제관찰자(concrete observer) 이다

Subject
Subject는 자신의 관찰자를 알고 있고, 이들을 추가했다 삭제할 수 있는 인터페이스를 제공한다. 얼마나 많은 관찰자 오브젝트들이 이 주제(subject)를 관찰할지 모른다.

Concrete subject
실제 주제(concrete subject)는 고나심 상태(state)를 실제 관찰자 오브젝들에 저장한다. 그리고 상태 변경에 따라 상태가 변경되었다는 적절한 통지를 보낸다

Observer
관찰자(observer)는 주제가 변경되었을 때 이 변경 내용을 통지 받을 오브젝트들을 위한 수정 인터페이스를 정의한다

Concrete observer
실제 관찰자(concrete observer)는 실제 주제 오브젝트의 참조를 유지한다. 추가적으로, 주제의 상태와 동기화되기 위해 별도의 상태를 저장하고 관찰자 수정 인터페이스의구현을 제공한다


먼저, AirlineSchedule 클래스라는 예제를 사용해서 주제(subject)를 구현할 것이다. 누가 봐도 이클래스의 생성자는 아주 직관적이다. 여기에는 항공사의 이름, 출발 도시, 도착 도시, 출발 시간의 정보를 가지고 있다.





이 클래스는 네 개의 프로퍼티를 선언하는데, 야간 특이한 것이 하나 있다. 이는 바로 DepartureDateTime프로퍼티인테 , 이 프로퍼티는 멤버 변수를 설정할 뿐만 아니라 OnChange()이벤트를 일으킨다

이때 발생하는 이벤트는 다음과 같다

public event ChangeEventHandler<AirlineSchedule , ShangeEventArgs> Change;

// Change 이벤트를 일으킨다

public virtual void OnChange(ChangeEventArgs e)
{
if(Change != null)
{
                        Change(this, e);
            }
}



주제의 핵심 기능은 관찰자(Observer)를 추가하고 삭제할 수 있는 인터페이스르 ㄹ제공하는 것이다 이를 위해 다음 처럼 Attach()와 Detach()메소드를 사용한다.

public void Attach(AirTrafficControl airTrafficControl)
{
     Change +=new ChangeEventHandler<AirlineSchedule, ChangeEventArgs> (airTrafficControl.Update);
}

public void Detach(AirTrafficControl airTrafficControl)
{
     Change -= new ChangeEvenHandeler<AirlineSchedule, ChangeEventArgs> (airTrafficeControl.Update);
}

실제 주제(concrete subject)클래스는 관심 상태를 관찰자들에게 제공한다. 또한 기반 클래스(주로, 주제 클래스)의 Notify() 메소드를 호출해서 모든 관찰자에게 통지를 보낸다.
이를 위해 다음과 같이 간단한 예제를 제공할 것이다

// 설제 주제 (concrete subject)
class CarrierSchedule : AirlineSchedule
{
     // 제시와 알렉스는 정해진 한 장소로 가는 비행기를 타려고 한다.
     public CarrierSchedule(string name, DateTime departing) : base(name,"Boston","Seattle", departing)
    {
    }
}


관찰자 클래스는 모든 관찰자들을 위해 수정 인터페이스를 제공하며, 이를 통해 관찰자들이 주제(subject)에서
수정 통지를 받을 수 있도록 해준다. 그래서, 주제에 관심을 지켜보려는 관찰자들은 이 인터페이스를 구현해야 한다. 이 인터페이스는 다음과 같은 Update()라는 단일 메소드를 구현할 필요가 있다.


interface IATC
{
    void Update(AirlineSchedule sender, ChangeEventArgs e);
}

각 실제 관찰자(concrete observer)는 주제는 상태가 변경될 때 통지를 받을 수 있도록 실제 주제(concrete subject)에 팜조를 유지한다.

확인할 수 있듯이,  실제 관찰자 클래스에서 Update() 메소드를 재정의한다. 주제가 Update()메소드를 호출할 떄, 실제 관찰자(concrete observer)는 Update()를 구현하고 변경 통지가 일어낫을 떄 이를 처리할 독자적인 로직을 정의한다.


//실제 관찰자 (concrete observer)
class AirTrafficeControl : IATC
{
   public string Name {get; set;}
   public CarrierSchedule CarrierSchedule{get;set;}
 
   // 생성자
   public AirTrafficControl(stirng name)
   {
      this.Name = name;
   }

   public void Update(AirlineSchedule sender, ChangeEventArgs e)
   {
      Console.WriteLine("{0} Air Traffic Control Notified:\n {1}'s flight 497 from {2} " +
      "to {3} new departure time :{4:hh:mmtt}", Name, e.Airline, e.DepartureAirport, 
       e.ArrivalAirport, e.DepartureDateTime);
       Console.WriteLine("---------------");
    }
 
}



코드에서 실행하기


이 Observer 패턴을 실행해 보기 위해, 지금까지 만든 클래스들을 사용할 별도의 코드가 필요할 것이다. 다음은 간단한 콘솔 프로그램의 전체 코드이다

class Program
{

   static void Main()
  {
       DateTitme now = DateTime.Now;
       // 출발 시간과 목적지가 있는  새로운 비행편을 만든다.
       CarrierSchedule jetBlue = new CarrierSchedule("JetBlue", noew);
       JetBlue.Attach(new AirTrafficControl("Boston"));
       JetBlue.Attach(new AirTrafficControl("Seattle"));

        // ATC 클래스들은 출발 시간의 연기를 통지할것이다

        jetBlue.DepartureDateTime = now.AddHours(1.25); //날씨 때문에 연기
        jetBlue.DepartureDateTime = now.AddHours(2.75); // 날씨가 더 악화됨
        jetBlue.DepartureDateTime = now.AddHours(3.5); //보안 때문에 연기
        jetBlue.DepartureDateTitme = now.AddHours(3.75); // 시애틀 출발시간

       // 승객 대기

       console.Read();
   }
}



관찰자 패턴을 실행할 C# 콘솔 프로그램의 전체 코드와 파일




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Observer
{

    class Program
    {
        static void Main()
        {
            DateTime now = DateTime.Now;

            //출발 시간과 목적지가 있는  새로운 비행편을 만든다

            CarrierSchedule jetBlue = new CarrierSchedule("JetBlue", now);
            jetBlue.Attach(new AirTrafficControl("Boston"));
            jetBlue.Attach(new AirTrafficControl("Seattle"));
            //ATC 클래스들은 출발 시간의 연기를 통지할 것이다
            jetBlue.DepartureDateTime = now.AddHours(1.25);// 날씨 때문에 연기
            jetBlue.DepartureDateTime = now.AddHours(1.75); //날씨가 더 악화됨
            jetBlue.DepartureDateTime = now.AddHours(0.5); //보안 떄문에 연기
            jetBlue.DepartureDateTime = now.AddHours(0.75); //시애틀 출발 시간

            // 승객 대기
            Console.Read();
        }
    }
    // 비행 스케줄 요청을 가로채기 위한 제네릭 델리게이트 타입 선언
    public delegate void ChangeEventhandler<T, U>(T sender, U eventArgs);

    // 실행에 맞는 이벤트 인수를 설정

    public class ChangeEventArgs : EventArgs
    {
        public string Airline { get; set; }
        public string DepartureAirport { get; set; }
        public string ArrivalAirport { get; set; }
        public DateTime DepartureDateTime { get; set; }

        public ChangeEventArgs(string name, string outAirport, string inAirport, DateTime leaves)
        {
            this.Airline = name;
            this.DepartureAirport = outAirport;
            this.ArrivalAirport = inAirport;
            this.DepartureDateTime = leaves;
        }


    }  // 주제 : Air Traffic Control 센터에서 관찰하게 되는 대상이다
    abstract class AirlineSchedule
    {
        public string Name { get; set; }
        public string DepartureAirport { get; set; }
        public string ArrivalAirport { get; set; }
        private DateTime departuredateTime;

        public AirlineSchedule(string ariline, string outAirport, string inAiport, DateTime leaves)
        {
            this.Name = ariline;
            this.DepartureAirport = outAirport;
            this.ArrivalAirport = inAiport;
            this.departuredateTime = leaves;
        }

        // 이벤트

        public event ChangeEventhandler<AirlineSchedule, ChangeEventArgs> Change;

        // Change 이벤트를 일으킨다
        public virtual void OnChange(ChangeEventArgs e)
        {
            if (Change != null)
            {
                Change(this, e);
            }
        }

        // 관찰자(observer)들을 실제로 추가하는 부분
        public void Attach(AirTrafficControl airTrafficControl)
        {
            Change += new ChangeEventhandler<AirlineSchedule, ChangeEventArgs>(airTrafficControl.Update);
        }

        public void Detach(AirTrafficControl airTrafficControl)
        {
            Change -= new ChangeEventhandler<AirlineSchedule, ChangeEventArgs>(airTrafficControl.Update);
        }

        public DateTime DepartureDateTime
        {
            get { return departuredateTime; }
            set
            {
                departuredateTime = value;
                OnChange(new ChangeEventArgs(this.Name, this.DepartureAirport, this.ArrivalAirport, this.departuredateTime));
                Console.WriteLine("<br/>");
            }
        }

    }


    // 실제 주제(concrete subect)
    class CarrierSchedule : AirlineSchedule
    {
        // 제시와 알렉스는 실제 한 곳으로만 비행할 곳을 한다
        public CarrierSchedule(string name, DateTime departing)
            : base(name, "Boston", "Seattle", departing)
        {

        }

    }

    // 관찰자
    interface IATC
    {
        void Update(AirlineSchedule sender, ChangeEventArgs e);
    }
    // 실제 관찰자
    class AirTrafficControl : IATC
    {
        public string Name { get; set; }

        // 생성자
        public AirTrafficControl(string name)
        {
            this.Name = name;
        }
        public void Update(AirlineSchedule sender, ChangeEventArgs e)
        {
            Console.WriteLine("{0} Air Traffic Control Notified :\n {1}'s flight 497 from {2} " +
                "to {3} new departure time : {4:hh:mmtt}", Name, e.ArrivalAirport, e.DepartureAirport, e.ArrivalAirport, e.DepartureDateTime);
            Console.WriteLine("------------------");
        }
        public CarrierSchedule CarrierSchedule { get; set; }
    }

}

 




- 참고  Programming .Net 3.5 by Jesse Liberty and Alex Horovitz.

신고
Trackback 0 Comment 0
2008.09.04 19:48

C#으로 이미지 리사이즈/조작 시 부드럽게 렌더링 하기

간단한 팁.
C#에서 GDI+의 Graphics 오브젝트를 사용해서 렌더링을 할 때 사이즈 변경 등의 변형이 일어나면 들쭉날쭉한 도트가 심해지는 현상이 있는데요, 간단하게 InterpolationMode를 설정하여 렌더링 방식을 선택할 수 있네요.

Image img = Image.FromFile("a.jpg");

using (Bitmap bitmap = new Bitmap(img.Width, img.Height))

{

using (Graphics g = Graphics.FromImage(bitmap))

{

        // 드로잉 모드

        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        // 메모리에 렌더링

        g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));

// 파일 저장

        bitmap.Save("a.png");

}

}

내친김에 간단한 윈폼 프로젝트를 하나 만들어서 각 모드별 차이점을 찾아봤어요.


이미지를 선택하면 무조건 200 x 200 사이즈로 렌더링 하는데요, 각 모드별로 걸리는 시간도 함께 표시했어요.


각 모드별로 구분이 확실히 되죠? High...시리즈가 확실히 품질이 더 좋지만 리사이즈에 시간이 훨씬 더 걸리죠.


InterpolationMode는 텍스트나 직선이 많이 들어갈 때 더 확실히 차이가 나는데요, High...시리즈는 흐릿하지만 어느 정도 글자를 읽을 수 있게 되죠.


대용량 사진으로 테스트. 가장 시간이 많이 걸리는건 HighQualityBilinear 방식이고요, 계산을 더 할 수록 이미지가 부드러워지는 혹은 흐려지는 경향이 있네요. HighQualityBilinear는 원본 이미지가 너무 뭉개지는 감이 있고요, HighQualityBicubic이 적당해 보여요.

특히 Deepzoom을 사용할 때에는 이미지가 가급적 부드러운 쪽이 더 자연스러운 확대축소 효과를 보여주게 되므로 혹시 Deepzoom을 위한 이미지를 코드로 리사이즈 한다면 부드러우면서도 약간이나마 더 빠른 HighQualityBicubic쪽을 추천해요.


출처: http://gongdo.tistory.com/

신고
Trackback 11 Comment 0
2008.08.28 08:49

ASP.NET 2개 폼 사용하는 꽁수

태요님에 강좌중에 찾은 Form 2개 사용...

http://taeyo.pe.kr/Columns/View.aspx?SEQ=81&PSEQ=8&IDX=0
신고
Trackback 0 Comment 0
2008.08.28 08:25

하나의 클래스를 통째로 넘기는 방법 ( a.aspx.cs -> b.aspx.cs )

A.aspx.cs
------------------------------------------------------------
public partial class A : System.Web.UI.Page
{
    public string strTest { get { return "123"; } }
   protected void Page_Load(object sender, EventArgs e)
    {
   }
    protected void Button1_Click(object sender, EventArgs e)
    {
        Server.Transfer("test2.aspx");
    }
}


B.aspx.cs

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

public partial class B: System.Web.UI.Page
{
   
    protected void Page_Load(object sender, EventArgs e)
    {
        A a = (A)Context.Handler;

        Response.Write(a.strTest);        

    }
}

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

출처 : http://hoons.kr/Board.aspx?Name=QAASPNET&Mode=2&BoardIdx=14931&Key=&Value=
신고
Trackback 0 Comment 0


티스토리 툴바