Study/C# - 해당되는 글 16건
기존의 프로그래밍에서는 파일의 경로부분을 얻기위해, split()나, mid(), right() 메서드 등을 사용하였습니다. 하지만 C#.NET에서는 Path객체를 통해서 확장자 부분만 얻기 외에 다수의 파일경로에 대한 처리를 지원하고 있습니다.

1. 먼저 사용하기 위해서는 using System.IO;를 선언해야합니다.
2. Path객체를 특별히 따로 선언해서 사용하는 것이아니라, static 메서드를 활용하여 경로부분을 원하는데로 다룰 수 있게 됩니다.
  • Path.ChangeExtension(string path) : 경로문자열에서 확장명 부분을 변경합니다.
  • Path.GetDirectoryName(string path) : 경로문자열에서 파일이름을 제외한 경로부분(디렉터리명)을 반환 합니다.
  • Path.GetExtension(string path) : 경로문자열에서 확장명 부분만 반환합니다.
  • Path.HasExtension(string path) : 경로문자열에서 확장명 부분이 있는지 확인하여 bool값으로 반환합니다.
  • Path.GetFileName(string path) : 경로문자열에서 파일이름부분을 반환합니다.
  • Path.GetFileNameWithoutExtension(string path) : 경로문자열에서 확장명부분을 제외한 파일이름을 반환합니다.
  • Path.GetFullPath(string path) : 경로문자열에 해당하는 절대경로를 반환합니다.
  • Path.GetPathRoot(string path) : 경로문자열에서 루트디렉터리(드라이브 명) 부분만 반환합니다.
  • Path.GetRandomFileName() : 파일 또는 폴더명으로 사용가능한 임의의 문자열을 반환합니다.
  • Path.GetTempFileName() : 임의로 임시파일을 생성 후, 생성된 임시파일의 경로를 반환합니다. 임시파일은 시스템의 지정된 임시폴더(Temp)에 생성됩니다.
  • Path.GetTempPath() : 시스템에 지정된 임시폴더의 경로를 반환합니다.
  • Path.IsPathRooted(string path) : 매개변수로 지정된 경로문자열이 상대경로인지 절대경로인지 파악하여 bool값으로 반환합니다. 절대경로이면 true를 반환합니다.
  • Path.GetInvalidFileNameChars() : 파일이름으로 부적합한 문자들의 배열을 반환합니다.
  • Path.GetInvalidPathChars() : 경로명으로 부적합한 문자들의 배열을 반환합니다.
저작자 표시
신고
Trackback 0 | Comment 0
        /// <summary>
        /// URL에 해당하는 웹페이지의 이미지를 가져온다.
        /// </summary>
        /// <param name="URL">가져오고자 하는 URL</param>
        /// <returns>해당 웹페이지의 이미지</returns>
        public Bitmap getImageFromURL(String URL)
        {
            // WebBrowser를 생성하고 자동으로 Dispose해주기 위해 Using Keyword를 사용
            using (WebBrowser WebBrowser = new WebBrowser())
            {
                // 캡쳐될 화면에 스크롤바를 포함시키지 않을것이므로.
                WebBrowser.ScrollBarsEnabled = false;
                WebBrowser.TabStop = false;

                try
                {
                    Bitmap Result = null;   // 웹페이지 이미지가 저장될공간

                    // 웹페이지가 모두 로드가 되었을때 발생하는 이벤트.
                    // 간단하게 함수하나로 해결하기 위해 인라인 Delegate를 사용
                    WebBrowser.DocumentCompleted +=
                        delegate(object sender, WebBrowserDocumentCompletedEventArgs e)
                    {
                        // WebBrowser가 정말로 Complate되었는지 확인하기 위함
                        if (WebBrowser.ReadyState != WebBrowserReadyState.Complete) return;

                        // 문서의 크기만큼 웹브라우저의 크기를 조절 (스크롤바 안생기게하려고)
                        int ScrollWidth = WebBrowser.Document.Body.ScrollRectangle.Width;
                        int ScrollHeight = WebBrowser.Document.Body.ScrollRectangle.Height;
                        Size PageSize = new Size(ScrollWidth, ScrollHeight);
                        WebBrowser.Size = PageSize;

                        // 문서 크기만큼의 이미지를 생성
                        Result = new Bitmap(PageSize.Width, PageSize.Height);

                        // 위에서 생성한 이미지에 WebBrowser Rendering (.Net 2.0이상에서만 지원)
                        WebBrowser.DrawToBitmap(Result, new Rectangle(Point.Empty, PageSize));

                    };

                    // 요청한 URL로 이동
                    WebBrowser.Navigate(URL);

                    // Result에 데이터가 들어올때 까지 대기후 리턴
                    while (Result == null) Application.DoEvents();

                    
                    return Result;

                }
                catch (Exception)
                {
                    return null;
                }
            }
        }
저작자 표시
신고
Trackback 0 | Comment 0

1.Introduction

 

이번 아티글에서는 이미지 객체를 다루는 예제를 살펴 보려한다. 오늘 실습할 작업은 두가지 이다. 이미지를 메모리로 읽어와서 이미지의 특정 영역만 잘라서 저장을 하는 작업과 특정 퍼센트로 이미지 크기를 조절해보는 작업을 해보도록 하겠다.

 

2.Percent Adjust Code

 

먼저 원본 이미지를 읽어서 늘려서 저장을 해보고 줄여서 저장을 해보는 작업을 먼저 해보도록 하겠다.
 

[Main함수]

static void Main(string[] args)

{

        //원본이미지및 디렉토리 설정

        string Directory = @"img";

        Image imgPrettyGirl = Image.FromFile(Directory + @"Girl.jpg");

        Image imgSavePhoto = null;

        //퍼센트로 줄이기 : 250% 늘리기

        imgSavePhoto = ScaleByPercent(imgPrettyGirl, 250);

        imgSavePhoto.Save(Directory + @"ResizeImgPercentageImg1.jpg", ImageFormat.Jpeg);

        imgSavePhoto.Dispose();

        //퍼센트로 줄이기 : 50% 줄이기

        imgSavePhoto = ScaleByPercent(imgPrettyGirl, 50);

        imgSavePhoto.Save(Directory + @"ResizeImgPercentageImg1.jpg", ImageFormat.Jpeg);

        imgSavePhoto.Dispose();

}

 


메인 함수를 살펴보자. imgPrettyGirl 객체 만들고 지정경로에서 원본이미지를 읽어 오게 된다. 그리고 ScaleByPercent라는 함수를 호출한다. 이제 ScaleByPercent() 함수를 살펴 보도록 하자.
 

/// <summary>

/// 퍼센트로 줄이기

/// </summary>

/// <param name="imgPhoto">사진 객체</param>

/// <param name="Percent">퍼센트</param>

/// <returns>수정된 Image</returns>

static Image ScaleByPercent(Image imgPhoto, int Percent)

{

        //퍼센트 0.8 or 0.5 ..

        float nPercent = ((float)Percent/100);

        //넓이와 높이

        int OriginalWidth = imgPhoto.Width;

        int OriginalHeight = imgPhoto.Height;

        //소스의 처음 위치

        int OriginalX = 0;

        int OriginalY = 0;

        //움직일 위치

        int adjustX = 0;

        int adjustY = 0;

        //조절될 퍼센트 계산

        int adjustWidth  = (int)(OriginalWidth * nPercent);

        int adjustHeight = (int)(OriginalHeight * nPercent);

        //비어있는 비트맵 객체 생성

        Bitmap bmPhoto = new Bitmap(adjustWidth, adjustHeight, PixelFormat.Format24bppRgb);

        //이미지를 그래픽 객체로 만든다.

        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        //사각형을 그린다.

        //그릴 이미지객체 크기, 그려질 이미지객체 크기

        grPhoto.DrawImage(imgPhoto,

               new Rectangle(adjustX,adjustY,adjustWidth,adjustHeight),

               new Rectangle(OriginalX,OriginalY,OriginalWidth,OriginalHeight),

               GraphicsUnit.Pixel);

        grPhoto.Dispose();

        return bmPhoto;

}

 


주석을 정말 자세하게 달아 보았다. 특별히 설명할 코드느 없어 보인다. 중요한건 편집 되어져가는 흐름은 알아 두어야 한다. 먼저 이미지 비트맵(빈종이)을 생성하게 되고 그 위에 Graphic객체를 이용하여 원본이미지를 붙여 넣게 되는 흐름인 것이다.

 

3.Image Crop Code
 

이번에는 원본 이미지에 특정 영역을 잡아서 저장하는 작업을 살펴보자.

[메인함수]

static void Main(string[] args)

{

        //원본이미지및 디렉토리 설정

        string Directory = @"img";

        Image imgPrettyGirl = Image.FromFile(Directory + @"Girl.jpg");

        Image imgSavePhoto = null;

        //자 르 기

        imgSavePhoto = Crop(imgPrettyGirl, 100,150,0,0);

        imgSavePhoto.Save(Directory + @"ResizeImgMvpGirl.jpg", ImageFormat.Jpeg);

        imgSavePhoto.Dispose();

}


위의 메인 함수에서 역시 Crop이라는 메소드를 호출하고 있다. 그리고 특정영역 부분의 정보 역시 같이 보내고 있다. 그럼 Crop메서드는 어떻게 구현되어져 있는지 살펴 보도록 하자.
 

/// <summary>

/// 특정 위치의 이미지를 자른다.

/// </summary>

/// <param name="imgPhoto">이미지 사진</param>

/// <param name="Width">넓이</param>

/// <param name="Height">높이</param>

/// <param name="adjustX">X축 시작점</param>

/// <param name="adjustY">Y축 시작점</param>

/// <returns></returns>

static Image Crop(Image imgPhoto, int Width, int Height,int adjustX, int adjustY)

{

        //비트맵 종이한장 만들기

        Bitmap bmPhoto = new Bitmap(Width-adjustX, Height-adjustY, PixelFormat.Format24bppRgb);

        //그래픽 이미지 설정

        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        int OriginalWidth = imgPhoto.Width;

        int OriginalHeight = imgPhoto.Height;

        //싹뚝 자르기

        grPhoto.DrawImage(imgPhoto,

               new Rectangle(0,0,Width,Height),

               new Rectangle(adjustX,adjustY,Width,Height),

               GraphicsUnit.Pixel);

 

        grPhoto.Dispose();

        return bmPhoto;

}


오히려 Crop메서드가 훨씬 짧고 간결하게 구현 되어져 있다. 솔직히 이 메서드는 하는일이 별로 없다. 코드 안에 있는 DrawImage라는 메서드만 눈여겨 보면 된다. DrawImage는 30개 이상의 오버로드를 제공한다. 그렇기 때문에 기능도 많고 내가 하고자 하는 작업을 선택해 내기도 까다롭다. 그렇기 때문에 각자가 msdn을 보면서 작업을 해 나가야 할 것이다.
저작자 표시
신고
Trackback 0 | Comment 0

I have been tacking per-process CPU percentage and Network IO data bytes in my recent project using System.Diagnostics.PerformanceCounter class. I felt the online materials I found does not explain the usage of the PerformanceCounter very well.

Some basics about PerformanceCounter.
1. A performance category has many performance counters underneath. A performance counter may be single-instanced or contain multiple running instances. The structure is like this:

PerformanceCategory

    -- PerformanceCounter

        -- Instances

To get all the built-in categories:

PerformanceCategory.GetCategories()


To get all the counters under the category that has exactly one running instance:

PerformanceCategory.GetCounters()


2. The constructor to create a performance counter is:

PerformanceCounter(string categoryName, string counterName, string instanceName.


To monitor the IO (file or network) data bytes sent/received by FireFox:

PerformanceCounter counter = new PerformanceCounter("Process", "IO Data Bytes/sec", "firefox");


To monitor the CPU percentage used by FireFox:

PerformanceCounter counter = new PerformanceCounter("Process", "% Processor Time", "firefox");


3. To take a sample and get the calculated value:

counter.NextValue();

Before calling this method, make sure you wait for at least one second.

counters.Add(new PerformanceCounter("Process", "IO Data Bytes/sec", "firefox"));

counters.Add(new PerformanceCounter("Process", "% Processor Time", "firefox"));

 

System.Threading.Thread.Sleep(1000);

 

foreach(PerformanceCounter counter in counters)

        Console.WriteLine(string.Format("{0}:{1}}, counter.CounterName, counter.NextValue());


Some lessons I have learned:
1. The calculated value of the first sample is always 0. E.g. the very first time you call NextValue(), the returned value is always 0.

2. If an application has more than one running instances, even though from the Task Manager, these running instances all have the same process name, E.g. "TestProcess", their instance names are not the same. The instance started first has its name as "TestProcess", the second "TestProcess#1", the third "TestProcess#2"...the nth, "TestProcess#n". So make sure the right instance name gets passed into the performance counter constructor.

3. If any of the running instances of the same application exits, the instance names will be changed. If your code doesn't update the instance name accordingly, an "Instance not found" error will occur.

E.g. If "TestProcess" of the 2 running instances, "TestProcess" and "TestProcess#1", stopps running, "TestProcess#1" will be renamed to "TestProcess". If the counter still has the name "TestProcess#1", it will throw an exception when NextValue() is called. The instance name can be updated by simply calling counter.InstanceName = "new instance name".

4. In my case, I am only interested in getting per-Process statistics. Unfortunately, the PerformanceCounter does not operate against the process id. To get around this limitation, I have created my own wrapper class called ProcessPerformanceCounter.

public class ProcessPerformanceCounter

{

    ...

    public ProcessPerformanceCounter(string counterName, int processId) {...}

    public string CounterName {get{...}}

    public string InstanceName {get{...} set{...}}

    public NextValue(){...}

}


Based on the process id, I can get the process name. I can then get all running processes under the same name. From there, I can get the correct instance name for that particular process:

private string GetInstanceName(int processId)

{

        string instanceName = GetProcessNameById(processId);

        bool found = false;

        if (!string.IsNullOrEmpty(instanceName))

        {

                Process[] processes = Process.GetProcessesByName(instanceName);

                if (processes.Length > 0)

                {

                        int i = 0;

                        foreach (Process p in processes)

                        {

                                instanceName = FormatInstanceName(p.ProcessName, i);

                                if (PerformanceCounterCategory.CounterExists("ID Process","Process"))

                                {

                                        PerformanceCounter counter = new PerformanceCounter("Process", "ID Process", instanceName);

 

                                        if (processId == counter.RawValue)

                                        {

                                                found = true;

                                                break;

                                        }

                                }

                                i++;

                        }

                }

        }

 

        if (!found)

                instanceName = string.Empty;

 

        return instanceName;

 

private string FormatInstanceName(string processName, int count)

{

        string instanceName = string.Empty;

        if (count == 0)

                instanceName = processName;

        else

                instanceName = string.Format("{0}#{1}", processName, count);

        return instanceName;

 

5. When calling counter.NextValue(), do not forget to handle the instance name changed scenario:

public float NextValue()

{

        float nextValue = 0;

        try

        {

                nextValue = counter.NextValue();

        }

        catch (Exception ex)

        {

                if (InstanceNotExistError(ex))

                {

                        // adjust instance name based on process id

                        instanceName = GetInstanceName(processId);

                        counter.InstanceName = instanceName;

                        nextValue = counter.NextValue();

                }

                else

                        throw;

        }

 

        return nextValue;

}

 

저작자 표시
신고
Trackback 0 | Comment 0

윈도우를 종료
System.Diagnostics.Process.Start("cmd.exe","ShutDown.exe -s -f -t 00");


윈도우를 재부팅

System.Diagnostics.Process.Start("cmd.exe","ShutDown.exe -r -f -t 00");

 

특정 폴더 열기
System.Diagnostics.Process.Start("explorer.exe", "C:\Temp");

특정 사이트 열기
System.Diagnostics.Process.Start("explorer.exe", "http://www.naver.com");

 

도스명령어 실행

System.Diagnostics.Process.Start("cmd.exe","/c dir");

저작자 표시
신고
Trackback 0 | Comment 0

네임스페이스: System.Diagnostics

어셈블리: System(System.dll)

 

설명: Process 구성 요소는 컴퓨터에서 실행 중인 프로세스에 대한 액세스를 제공합니다. 간단히 말해 프로세스란 실행 중인 응용 프로그램을 말합니다. 스레드는 운영 체제에서 프로세서 시간을 할당하는 기본 단위입니다. 스레드는 현재 다른 스레드에서 실행 중인 코드 부분을 포함하여 프로세스의 모든 코드 부분을 실행할 수 있습니다.

Process 구성 요소는 응용 프로그램의 시작, 중지, 제어 및 모니터링을 위한 유용한 도구입니다. Process 구성 요소를 사용하면 실행 중인 프로세스의 목록을 얻거나 새로운 프로세스를 시작할 수 있습니다. 또한 Process 구성 요소를 사용하여 시스템 프로세스에도 액세스할 수 있습니다. Process 구성 요소를 초기화한 후에는 해당 구성 요소를 사용하여 실행 중인 프로세스에 대한 정보를 얻을 수 있으며 그러한 정보에는 스레드 집합, 로드된 모듈(.dll .exe 파일), 프로세스가 사용하고 있는 메모리 양과 같은 성능 정보 등이 포함됩니다.

따옴표를 사용하여 시스템에서 경로 변수를 선언한 경우 해당 위치에 있는 프로세스를 시작할 때 해당 경로를 정규화해야 합니다. 그렇지 않으면 시스템에서 경로를 찾지 않습니다.예를 들어 c:\mypath가 경로에 없는 경우 path = %path%;"c:\mypath"와 같이 따옴표를 사용하여 추가하면 시작할 때 c:\mypath의 모든 프로세스를 정규화해야 합니다.

프로세스 구성 요소는 속성 그룹에 대한 정보를 한 번에 가져옵니다. Process 구성 요소가 특정 그룹의 한 멤버에 대한 정보를 가져올 때 해당 그룹의 나머지 속성 값이 캐시되므로 Refresh 메서드를 호출하지 않는 한 그룹의 다른 멤버에 대한 새로운 정보를 가져오지 않습니다. 따라서 속성 값이 Refresh 메서드를 마지막으로 호출하여 얻은 속성 값과 같을 수 있습니다. 이러한 그룹 명세는 운영 체제에 따라 다릅니다.

시스템 프로세스는 시스템에서 해당 프로세스 식별자로 고유하게 식별됩니다. 많은 Windows 리소스와 마찬가지로 해당 핸들로도 프로세스를 식별할 수 있습니다. 그러나 이러한 핸들은 컴퓨터에서 고유하지 않습니다. 핸들은 리소스의 식별자를 나타내는 일반적인 용어입니다. 운영 체제에서는 프로세스가 종료된 후에도 프로세스 핸들을 지속시키며 Process 구성 요소의 Handle 속성을 통해 이 핸들에 액세스할 수 있습니다. 따라서 ExitCode(성공하면 0이고 오류가  발생하면 0이 아닌 값) ExitTime과 같은 프로세스에 대한 관리 정보를 가져올 수 있습니다 .핸들은 매우 중요한 리소스이므로 메모리 누수보다 핸들 누수가 더 심각합니다.

 

메서드

Close(): 해당 구성 요소에 연결된 리소스를 모두 해제 합니다.

GetProcessById(Int32): 로컬 컴퓨터의 프로세서에 대한 식별자가 주어지면 새 Process 구성 요소를 반환합니다.

GetProcess(): 로컬 컴퓨터의 각 프로세스 리소스에 대해 새 Process 구성 요소를 만듭니다.

Kill() 연결된 프로세스를 즉시 중지합니다.

OnExited(): Exited이벤트를 발생시킵니다.

Start(): Process 구성요소의 StartInfo 속성으로 지정된 프로세스 리소스를 시작하거나 다시 사용하여 구성 요소에 연결합니다.

WaitForExit(): 연결된 프로세스가 종료될 때까지 Process 구성요소를 무기한 대기하게 합니다.

 

속성

ExitCode: 연결된 프로세스가 종료될 때 연결된 프로세스에서 지정한 값을 가져옵니다.

ExitTime: 연결된 프로세스가 종료된 시간을 가져옵니다.

HasExited: 연결된 프로세스가 종료되었는지 여부를 나타내는 값을 가져옵니다.

Id: 연결된 프로세스의 고유 식별자를 가져옵니다.

MachineName: 연결된 프로세스가 실행 중인 컴퓨터 이름을 가져옵니다.

MainWindowTitle: 프로세스의 주 창에 대한 캡션을 가져옵니다.

ProcessName: 프로세스의 이름을 가져옵니다.

StartInfo: Process Start메서드에 전달할 속성을 가져오거나 설정합니다.

StartTime: 연결된 프로세스가 시작된 시간을 가져옵니다.

TotalProcessorTime: 해당 프로세스의 총 프로세서 시간을 가져옵니다.

UserProcessorTime: 해당 프로세스의 사용자 프로세서 시간을 가져옵니다.

VirtualMemorySize64: 연결된 프로세스에 할당된 가상 메모리의 양을 가져옵니다.

WorkingSet64: 연결된 프로세스에 할당된 실제 메모리의 양을 가져옵니다.

 

이벤트

Exited: 프로세스가 종료될 때 발생합니다.

저작자 표시
신고
Trackback 0 | Comment 0
I found this useful C# class in this MSDN forum that provides an easy way to enable and disable an application auto-run in Windows.

With a little modification, I made it to be easily called by any project. What you need to do is just pass in the 'Key Name' and 'Assembly Location' parameters.

Here is the complete class:

using Microsoft.Win32;

 

/// <summary>

/// Utility.

/// </summary>

public class Util

{

    private const string RUN_LOCATION = @"Software\Microsoft\Windows\CurrentVersion\Run";

 

    /// <summary>

    /// Sets the autostart value for the assembly.

    /// </summary>

    /// <param name="keyName">Registry Key Name</param>

    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>

    public static void SetAutoStart(string keyName, string assemblyLocation)

    {

        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);

        key.SetValue(keyName, assemblyLocation);

    }

 

    /// <summary>

    /// Returns whether auto start is enabled.

    /// </summary>

    /// <param name="keyName">Registry Key Name</param>

    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>

    public static bool IsAutoStartEnabled(string keyName, string assemblyLocation)

    {

        RegistryKey key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION);

        if (key == null)

            return false;

 

        string value = (string)key.GetValue(keyName);

        if (value == null)

            return false;

 

        return (value == assemblyLocation);

    }

 

    /// <summary>

    /// Unsets the autostart value for the assembly.

    /// </summary>

    /// <param name="keyName">Registry Key Name</param>

    public static void UnSetAutoStart(string keyName)

    {

        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);

        key.DeleteValue(keyName);

    }

}


Sample Usage:

string keyName = "MyProgramName";

string assemblyLocation = Assembly.GetExecutingAssembly().Location;  // Or the EXE path.

 

// Set Auto-start.

Util.SetAutoStart(keyName, assemblyLocation);

 

// Unset Auto-start.

if (Util.IsAutoStartEnabled(keyName, assemblyLocation))

    Util.UnSetAutoStart(keyName);


저작자 표시
신고
Trackback 0 | Comment 0

foreach (System.Diagnostics.Process procName in                                  System.Diagnostics.Process.GetProcesses())

{

       Console.WriteLine(procName.ToString());

}

저작자 표시
신고
Trackback 0 | Comment 0
@차이점
값 타입과 참조 타입의 근본적인 차이점은 데이터가 저장되는 메모리상의 위치이다. 값 타입은 크기가 작고 고정적이기 때문에 스택에 생성되며 참조 타입은 크고 가변적이기 때문에 동적으로 관리되는 힙에 생성된다. 저장 위치의 차이로 인해서 많은 파생 차이점들이 발생하며 관리하는 방법이나 대입 시의 효과 등이 달라진다.
- 값 타입은 선언만 하면 스택에 즉시 생성되므로 선언 직후부터 데이터를 저장하는 용도로 사용할 수 있다. 하지만 참조 타입은 선언에 의해 참조만 생성될 뿐이지 데이터를 저장할 수 있는 실제 메모리가 할당되는 것은 아니므로 선언 즉시 사용할 수 없다. 반드시 new 연산자로 메모리를 할당받아 초기화해야 한다.
- 데이터 저장에 사용된 기억 장소가 파괴되는 시기가 다르다. 값 타입은 변수를 선언한 메서드가 종료될 때나 소속된 객체가 사라질 때 자동으로 파괴된다. 참조 타입은 더 이상 참조하는 변수가 없을 때 가비지 컬렉터에 의해 파괴된다.
- 같은 타입의 변수로 대입할 때의 효과가 다르다. 값 타입은 복사에 의해 완전한 별개의 사본이 생성되며 복사 한 사본과 원본은 별개의 변수이다. 이 상태에서 사본을 변경해도 원본은 원래 값을 그대로 유지하며 원본을 바꿔도 사본이 변경되지는 않는다. 완전히 다른 두개의 변수가 생성되는 것이다. 이에 비해 참조 타입끼리의 대입은 힙에 할당된 데이터를 참조하는 참조자가 하나 더 늘어날 뿐 별도의 메모리가 추가로 할당되는 것은 아니다. 그래서 둘 중 하나를 변경하면 상대쪽도 같이 변경된다.

@변수의 범주
메서드를 호출할 때 인수로 값 타입과 참조 타입을 모두 전달할 수 있다. 인수 전달이란 메서드의 형식 인수에 호출원의 실인수를 대입하는 것이므로 형식 인수와 실인수의 관계는 앞서 연구해 본 바와 같다. 값 타입은 사본이 전달되며 참조 타입은 참조자가 전달되므로 메서드 내에서 형식 인수를 변경할 때의 효과가 다르다. 다음은 C#의 7개의 변수의 범주이다.
- 지역변수: 메서드의 내부 또는 특정한 {} 블록 내에 선언되는 변수이다. 블록 내에서만 사용되며 별도의 초기값 대입이 없으면 쓰레기 값을 가지며 메서드나 블록이 종료되면 자동으로 사라진다. 메서드가 재귀 호출되면 호출될 때마다 새로 생성된다. 정식 명칭은 블록 범위 변수이다.
- 인스턴스 변수: 클래스 선언문 내에 선언되며 클래스 타입의 객체에 소속된다. 객체가 생성될 때 같이 생성되고 객체가 파괴될 때까지 존재한다. 흔히 필드라고 부르는 멤버 변수가 이 범주에 속한다.
- 정적 변수: 클래스 내에 static 키워드와 함께 선언되며 객체가 아닌 클래스에 소속된다. 정적 변수는 객체가 생성되기 전에 이미 존재하며 프로그램이 종료되어야 사라진다. C의 전역 변수와 비슷한 특성을 가지되 클래스에 소속된다는 점이 다르다. C#에서 진정한 의미의 전역변수는 존재하지 않는다.
- 배열 요소: 배열의 한 요소로 생성된다. 배열이 생성될 때 같이 생성되며 배열이 해제될 때 파괴된다. 선언문에 초기값 목록이 있으면 이 목록대로 초기화되며 그렇지 않으면 디폴트값(보통0)으로 초기화된다.
-값 인수: 메서드의 인수로 선언되며 메서드가 호출될 때 생성된다. 호출원에서 전달한 실인수의 값으로 초기화되며 메서드가 리턴할때 파괴된다.
-참조 인수: 값 인수와 같되 앞에 ref라는 키워드를 붙인다. 실인수의 값으로 초기화되지 않고 실인수를 가리키는 참조자로 초기화된다.
- 출력용 인수: 참조 인수와 같되 앞에 out라는 키워드를 붙인다. 참조 인수로 전달되는 실인수는 반드시 초기화되어야 하지만 출력용 인수는 초기화되지 않아도 상관없다. 메서드는 출력용 인수에 값을 담아 호출원으로 돌려보내며 리턴하기 전에 반드시 대입해야 한다.
저작자 표시
신고
Trackback 0 | Comment 0
클래스는 객체 지향 프로그래밍의 중심이다. 닷넷의 기본 라이브러리는 클래스 라이브러리이므로 모든 것들이 클래스로 되어 있다. 따라서 닷넷을 잘 활용하기 위해서는 클래스를 만들고 활용하는 방법을 속속들이 잘 알고 있어야 한다. 클래스는 속성을 표현하는 데이터와 동작을 기술하는 함수의 묶음으로 정의되며 유식한 표현으로 필드와 메서드를 캡슐해 놓은 것이다.
기본적인 개념은 C++이나 자바의 클래스와 똑같지만 닷넷의 클래스는 C++에 비해 훨씬 더 기능적으로 확장되었으며 새로운 개념들이 존재한다. C++의 클래스는 변수와 함수를 가지는 정도이지만 닷넷의 클래스에는 이 외에도 프로퍼티, 델리게이트, 인덱서 등이 더 포함된다. 우리는 닷넷 라이브러리의 무수한 클래스들이 제공하는 메서드, 필드, 프로퍼티 등을 활용하여 원하는 프로그램을 빠르고 쉽게 작성할 수 있다.
저작자 표시
신고

'Study > C#' 카테고리의 다른 글

[C# : 현재 실행중인 Process 목록 구하기]  (0) 2010.08.01
[C# : 값 타입(Value)과 참조 타입(Reference)  (0) 2010.07.25
[C# : 클래스]  (0) 2010.07.25
[C# : 배열의 메서드]  (0) 2010.07.25
[C# : 콘솔의 여러가지 기능]  (0) 2010.07.25
[.NET : 닷넷의 네임스페이스]  (0) 2010.07.25
Trackback 0 | Comment 0

강군v's Blog is powered by Daum & tistory

 

티스토리 툴바