๐Ÿ’ป Programming Language/C#

5๋ฒˆ์งธ ์Šคํ„ฐ๋””

S.Honey 2022. 4. 9. 23:54

์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๋ž€?!!?

public delegate void EventHandler(object sender, EventArgs e); 
Public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e); 

  1. public delegate void EventHandler(object sender, EventArgs e);
    • ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋ฉ”์„œ๋“œ๋ฅผ ๋‚˜ํƒ€๋ƒ„
  2. Public delegate void EventHandler(object sender, TEventArgs e);
    • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•  ๋•Œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋ฉ”์„œ๋“œ๋ฅผ ๋‚˜ํƒ€๋ƒ„

  • ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์žˆ๋Š” e ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋ฉด 1 ๋ฒˆ ๋ฉ”์†Œ๋“œ์˜ ๊ฒฝ์šฐ ๋‘๋ฒˆ์งธ e ๊ฐ์ฒด๋Š” ์ด๋ฒคํŠธ์˜ ์œ ๋ฌด๋งŒ์„ ์•Œ๋ฆฌ๋ฉฐ ํ•ด๋‹น ๊ฐ์ฒด๋Š” ๋‚ด์šฉ์ด ์—†๋‹ค. => ์ฆ‰, ๋นˆ ๊ป๋ฐ๊ธฐ์ด๋‹ค.
  • 2๋ฒˆ ๋ฉ”์†Œ๋“œ์˜ ๊ฒฝ์šฐ ํ•ด๋‹น e ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜๋ฉฐ ์ด๋•Œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” EventArgs ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„์•ผ ํ•œ๋‹ค.

๋ฉ€ํ‹ฐ์บ์ŠคํŠธ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ => ์กฐ์‚ฌํ•ด๋ณด๊ณ  ์ •๋ฆฌํ•ด๋ณด์ž


์ถ”๊ฐ€์ ์œผ๋กœ ๋„คํŠธ์›Œํฌ์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฐœ๋…์ธ ์œ ๋‹›์บ์ŠคํŠธ, ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ, ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๊ฐœ๋…์— ๋Œ€ํ•ด์„œ๋„ ๋‹ค์‹œ ์ •๋ฆฌํ•ด๋ณด์ž


delegate์™€ event ํ‚ค์›Œ๋“œ

  • delegate๋Š” ์™ธ๋ถ€์—์„œ๋„ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • event ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•˜๋ฉด public ์ผ์ง€๋ผ๋„ ์™ธ๋ถ€์—์„œ ํ˜ธ์ถœ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋”ฐ๋ผ์„œ ํ”„๋กœ๊ทธ๋žจ์— ๋”ฐ๋ผ ํ•ด๋‹น ํ‚ค์›Œ๋“œ๋“ค์„ ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•ด์„œ ๊ตฌ์กฐ๋ฅผ ์งœ์•ผํ•œ๋‹ค.

reflection => ํด๋ž˜์Šค์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐœ๋…

  • ์‹คํ–‰์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœ๊ฐ€๋Šฅํ•˜๋ฉฐ private์œผ๋กœ ์„ ์–ธ๋œ ๋ฐ์ดํ„ฐ๋„ ๋ฝ‘์„ ์ˆ˜ ์žˆ๋‹ค. (๋‹จ, private์œผ๋กœ ์„ ์–ธ๋œ ๊ฒฝ์šฐ์—” ์กฐ๊ธˆ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ฐ€์ง€๊ณ  ์ถ”์ถœํ•ด์•ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฝ‘์„ ์ˆ˜ ์žˆ๋‹ค.)



๋‹ค์Œ ๋ฐœํ‘œ ํฌํ•จ ๋‚ด์šฉ๋“ค



Sortingํ• ๋•Œ ๋ฐ˜ํ™˜๊ฐ’์ด 0๋ณด๋‹ค ํฐ๊ฐ’, 0, 0๋ณด๋‹ค ์ž‘์€๊ฐ’์œผ๋กœ ์ •๋ ฌ์„ ํ•˜๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ผ๊นŒ?


                                             ∩  ∩
  • ํ—‰์‰ฌ ์ด๊ฑฐ ์ง„์งœ ํ•œ๋ฒˆ๋งŒ ๊ฐ€๋ฅด์ณ ์ฃผ์‹œ๋ฉด ์•ˆ๋ ๊นŒ์š” ?! (ใ… _ใ… )
                                            ⊂|    |⊃
                                              ∪  ∪

Func์—์„œ ๋ฐ˜ํ™˜ํƒ€์ž…์„ Tuple(ํŠœํ”Œ)๋กœ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ์„๊นŒ?


using System;

namespace FuncTest
{
    class MainApp
    {
        static void Main(string[] args)
        {
            Func<int> func1 = () => 10;
            // ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์—†์œผ๋ฉฐ ๋ฌด์กฐ๊ฑด intํ˜•๊ฐ’์ธ 10์„ ๋ฐ˜ํ™˜ 
            Console.WriteLine(func1()); // 10 ์ถœ๋ ฅ

            Func<int, int> func2 = (x) => x * 2;
            //์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” int ํ˜•์‹ ํ•˜๋‚˜, ๋ฐ˜ํ™˜ ํ˜•์‹๋„ int
            Console.WriteLine(func2(3)); // 6 ์ถœ๋ ฅ

            Func<int, int, int> func3 = (x, y) => x + y;
            //์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” int ํ˜•์‹ ๋‘˜, ๋ฐ˜ํ™˜ ํ˜•์‹๋„ int
            Console.WriteLine(func3(2, 3)); // 5 ์ถœ๋ ฅ

            Func<int, int, (int, int)> func4 = (x, y) => (x + y, x - y);
            //์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” int ํ˜•์‹ ๋‘˜, ๋ฐ˜ํ™˜ ํ˜•์‹๋„ int
            Console.WriteLine(func4(2, 3)); // (5,-1) ์ถœ๋ ฅ
        }
    }
}
Output

10
6
5
(5, -1)
  • ํ™•์ธํ•ด๋ณด๋‹ˆ Func์—์„œ ๋ฐ˜ํ™˜ํƒ€์ž…์„ ํŠœํ”Œ๋กœ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ๋“œ์•„!

์ฆ‰์‹œ์ฟผ๋ฆฌ & ์ง€์—ฐ์ฟผ๋ฆฌ ๋ฐ IQueryable & IEnumerable

  •  

Timer ์™€ FileSystemWatcher ๋ฅผ ์ด์šฉํ•œ ์˜ˆ์ œ ์‹ค์Šตํ•ด๋ณด๊ธฐ!!


  • C# ์—๋Š” ์„ธ๊ฐ€์ง€ Timer ๊ฐ€ ์žˆ๋‹ค.

1. System.Windows.Forms.Timer
    - ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ๊ฐ„๊ฒฉ๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํƒ€์ด๋จธ๋ฅผ ๊ตฌํ˜„
    - ์ด ํƒ€์ด๋„ˆ๋Š” Windows Forms ์‘์šฉํ”„๋กœ๊ทธ๋žจ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์ ํ™” ๋˜์—ˆ์œผ๋ฉฐ ์ฐฝ์—์„œ ์‚ฌ์šฉ

2. System.Threading.Timer
    - ์ง€์ •๋œ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณต

3. System.Timers.Timer
    - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋˜ํ’€์ด ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑ 

  • ๋‹ค์Œ์œผ๋กœ FileSystemWatcher ๊ฐ€ ์žˆ๋‹ค. ์ด๋Š” ํŠน์ • ํด๋” ๊ฒฝ๋กœ์˜ ๋ชจ๋“  ํŒŒ์ผ์— ๋Œ€ํ•ด ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋˜๋ฉด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์ค€๋‹ค.
FileSystemWatcher ์‚ฌ์šฉ๋ฐฉ๋ฒ•
1. FileSystemWatcher ์ƒ์„ฑ์ž ํ˜ธ์ถœ

2. ๊ฐ์‹œํ•  ํด๋” ์„ค์ •(Directory path)

3. ๊ฐ์‹œํ•  ํ•ญ๋ชฉ๋“ค ์„ค์ •(ํŒŒ์ผ ์ƒ์„ฑ, ํฌ๊ธฐ, ์ด๋ฆ„ ๋“ฑ๋“ฑ)

4. ๊ฐ์‹œํ•  ํŒŒ์ผ ์œ ํ˜• ์„ ํƒ => ์ด ๊ฒฝ์šฐ `*.*` = ๋ชจ๋“  ํŒŒ์ผ 

5. ๊ฐ์‹œํ•  ์ด๋ฒคํŠธ ์„ค์ • (์ƒ์„ฑ, ๋ณ€๊ฒฝ ...)

6. FileSystemWatcher ๊ฐ์‹œ ๋ชจ๋‹ˆํ„ฐ๋ง ํ™œ์„ฑํ™”

7. ๊ฐ์‹œํ•  ํด๋” ๋‚ด๋ถ€ ๋ณ€๊ฒฝ์‹œ event ํ˜ธ์ถœ

Timer ์‚ฌ์šฉ ์˜ˆ์ œ ์ฝ”๋“œ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;


public class Example
{
    private static Timer timer;

    public static void Main(string[] args)
    {
        SetTimer();
        Console.WriteLine("์ข…๋ฃŒํ•˜๊ณ  ์‹ถ์œผ๋ฉด Enter ํ‚ค๋ฅผ ๋ˆ„๋ฅด์„ธ์š”!");
        Console.WriteLine("ํ˜„์žฌ ์‹œ๊ฐ„ : {0:HH:mm:ss.ff}",DateTime.Now);
        Console.ReadLine();
        timer.Stop();
        timer.Dispose();

        Console.WriteLine("์ข…๋ฃŒ..");
        Console.WriteLine();
    }

    private static void SetTimer()
    {
        timer = new Timer(5000);
        //์ฃผ๊ธฐ 20์ดˆ ์„ค์ •
        timer.Elapsed += alarm;
        //alarmํ•จ์ˆ˜ ์ถ”๊ฐ€
        timer.AutoReset = true;
        timer.Enabled = true;
    }

    private static void alarm(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! {0:HH:mm:ss.ff}",e.SignalTime);
    }
}
Output

์ข…๋ฃŒํ•˜๊ณ  ์‹ถ์œผ๋ฉด Enter ํ‚ค๋ฅผ ๋ˆ„๋ฅด์„ธ์š”!
ํ˜„์žฌ ์‹œ๊ฐ„ : 15:01:11.45
์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! 15:01:16.46
์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! 15:01:21.47
์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! 15:01:26.48
์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! 15:01:31.48
์•Œ๋žŒ!! ์•Œ๋žŒ!! ์•Œ๋žŒ!! 15:01:36.49

์ข…๋ฃŒ..

FileSystemWatcher ์‚ฌ์šฉ ์˜ˆ์ œ ์ฝ”๋“œ
using System;
using System.IO;

namespace MyNamespace
{
    class MyClassCS
    {
        static void Main()
        {
            using var watcher = new FileSystemWatcher(@"C:\test");
            //FileSystemWatcher ์ƒ์„ฑ์ž ํ˜ธ์ถœ ๋ฐ ๊ฐ์‹œํ•  ํด๋” ์„ค์ •

            watcher.NotifyFilter = NotifyFilters.Attributes
                                 | NotifyFilters.CreationTime
                                 | NotifyFilters.DirectoryName
                                 | NotifyFilters.FileName
                                 | NotifyFilters.LastAccess
                                 | NotifyFilters.LastWrite
                                 | NotifyFilters.Security
                                 | NotifyFilters.Size;
            // ๊ฐ์‹œํ•  ํ•ญ๋ชฉ๋“ค => ํŒŒ์ผ ์ƒ์„ฑ, ํฌ๊ธฐ, ์ด๋ฆ„ ๋“ฑ๋“ฑ 

            watcher.Changed += OnChanged;
            watcher.Created += OnCreated;
            watcher.Deleted += OnDeleted;
            watcher.Renamed += OnRenamed;
            watcher.Error += OnError;
            // ๊ฐ์‹œํ•  ์ด๋ฒคํŠธ ์„ค์ •(์ƒ์„ฑ, ๋ณ€๊ฒฝ, ์‚ญ์ œ ....)

            watcher.Filter = "*.txt";
            // ๊ฐ์‹œํ•  ํŒŒ์ผ ์œ ํ˜• ์„ ํƒ

            watcher.IncludeSubdirectories = true;
            watcher.EnableRaisingEvents = true;


            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }

        private static void OnChanged(object sender, FileSystemEventArgs e)
        {
            if (e.ChangeType != WatcherChangeTypes.Changed)
            {
                return;
            }
            Console.WriteLine($"Changed: {e.FullPath}");
        }

        private static void OnCreated(object sender, FileSystemEventArgs e)
        {
            string value = $"Created: {e.FullPath}";
            Console.WriteLine(value);
        }

        private static void OnDeleted(object sender, FileSystemEventArgs e) =>
            Console.WriteLine($"Deleted: {e.FullPath}");

        private static void OnRenamed(object sender, RenamedEventArgs e)
        {
            Console.WriteLine($"Renamed:");
            Console.WriteLine($"    Old: {e.OldFullPath}");
            Console.WriteLine($"    New: {e.FullPath}");
        }

        private static void OnError(object sender, ErrorEventArgs e) =>
            PrintException(e.GetException());

        private static void PrintException(Exception? ex)
        {
            if (ex != null)
            {
                Console.WriteLine($"Message: {ex.Message}");
                Console.WriteLine("Stacktrace:");
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine();
                PrintException(ex.InnerException);
            }
        }
    }
}
Output

Changed: C:\test\asdfad.txt
Changed: C:\test\asdfad.txt
Deleted: C:\test\asdfad.txt

์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์› ๋˜ ์ฝ”๋“œ ~

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static Timer timer;
    //Timer ๊ฐ์ฒด

    static void Main(string[] args)
    {
        var timerState = new TimerState { Counter = 0 };
        timer = new Timer(callback: new TimerCallback(TimerTask), state: timerState, dueTime: 1000, period: 2000);

        //Timer ์ธ์Šคํ„ด์Šคํ™” => dueTime์€ Timer ๊ฐ€ ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ๋Œ€๊ธฐ(์ง€์—ฐ)์‹œ๊ฐ„์ด๋ฉฐ period๋Š” ๋ฐ˜๋ณต ์ฃผ๊ธฐ์ด๋‹ค.

        while (timerState.Counter < 10)
        {
            Task.Delay(1000).Wait();
            // 1์ดˆ๋ฅผ ์ง€์—ฐ์‹œํ‚จ๋’ค while ์ œ์–ด๋ฌธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
            // ์ด๋•Œ ์ž”์ž‘์—…์ด ๋‚จ์•˜์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์ž‘์—…๋“ค์— ๋Œ€ํ•ด Wait()์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•จ 
        }

        timer.Dispose();
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
    }

    private static void TimerTask(object timerState)
    {

        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
        var state = timerState as TimerState;
        Interlocked.Increment(ref state.Counter);
    }

    class TimerState
    {
        public int Counter;
    }
}
Output

16:58:29.118: starting a new callback.
16:58:31.135: starting a new callback.
16:58:33.129: starting a new callback.
16:58:35.132: starting a new callback.
16:58:37.134: starting a new callback.
16:58:39.125: starting a new callback.
16:58:41.128: starting a new callback.
16:58:43.126: starting a new callback.
16:58:45.134: starting a new callback.
16:58:47.122: starting a new callback.
16:58:47.277: done.

LINQ ํ‘œ์ค€ ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ ์˜ˆ์ œ

using System;
using System.Linq;

namespace MinMaxAvg
{
    class Profile
    {
        public string Name { get; set; }
        public int Height { get; set; }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
            Profile[] arrProfile =
            {
                new Profile() { Name="์ •์šฐ์„ฑ" , Height = 186},
                new Profile() { Name="๊น€ํƒœํฌ" , Height = 158},
                new Profile() { Name="๊ณ ํ˜„์ •" , Height = 172},
                new Profile() { Name="์ด๋ฌธ์„ธ" , Height = 178},
                new Profile() { Name="ํ•˜ํ•˜" , Height = 171}
            };

            var profiles = arrProfile
                .Where(profile => profile.Height < 175)
                .OrderBy(profile => profile.Height)
                .Select(profile => new
                {
                    Name = profile.Name,
                    InchHeight = profile.Height * 0.393
                });

            Console.WriteLine("-------Linq ๋ฐ˜ํ™˜ ์ปฌ๋ ‰์…˜-------");
            foreach (var profile in profiles)
            {
                Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight);
            }

            Console.WriteLine("\n-------FirstOrDefault-------");
            Console.WriteLine(profiles.FirstOrDefault());
            // ์ปฌ๋ ‰์…˜์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜, ๋งŒ์ผ ์ปฌ๋ ‰์…˜ ๋‚ด ์›์†Œ๊ฐ€ ์—†๋‹ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜

            Console.WriteLine("\n-------ToList-------");

            var ListProfiles = profiles.ToList();

            foreach (var profile in ListProfiles)
            {
                Console.WriteLine("{0}, {1}", profile.Name, profile.InchHeight);
            }

            Console.WriteLine("\n-------ToDictionary-------");

            var DicProfiles = profiles.ToDictionary(profile => profile.Name, profile => profile.InchHeight);
            // Key ๋กœ profile.Name์„ ์‚ฌ์šฉ, Element๋กœ InchHeight๋ฅผ ์‚ฌ์šฉ => (this source(์ƒ๋žต๊ฐ€๋Šฅ), KeySelector, ElementSelector)
            for (int i = 0; i < DicProfiles.Count; i++)
            {
                Console.WriteLine(DicProfiles[ListProfiles[i].Name]);
            }
        }

    }
}
Output

-------Linq ๋ฐ˜ํ™˜ ์ปฌ๋ ‰์…˜-------
๊น€ํƒœํฌ, 62.094
ํ•˜ํ•˜, 67.203
๊ณ ํ˜„์ •, 67.596

-------FirstOrDefault-------
{ Name = ๊น€ํƒœํฌ, InchHeight = 62.094 }

-------ToList-------
๊น€ํƒœํฌ, 62.094
ํ•˜ํ•˜, 67.203
๊ณ ํ˜„์ •, 67.596

-------ToDictionary-------
62.094
67.203
67.596