C#๐Ÿ’‰์—์„œ ๋” ํšจ์œจ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๊ธฐ ์œ„ํ•œ 5๊ฐ€์ง€ (์™ธ๊ณผ์ ) ํŒ

9977 ๋‹จ์–ด csharpdotnetproductivitytutorial
ํšจ์œจ์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์‰ฌ์šด ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์„ ํ˜ธํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ™˜๊ฒฝ์— ๊ด€๊ณ„์—†์ด C#์—์„œ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•  ์ˆ˜ ์žˆ๋Š” 5๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. Microsoft Visual Studio๋ฅผ ์‚ฌ์šฉํ•˜๋“  ๋‹ค๋ฅธ IDE๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์ด ์กฐ์–ธ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ˆ ์„ ๋น ๋ฅด๊ณ  ์‰ฝ๊ณ  ํšจ์œจ์ ์œผ๋กœ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ๋งค์šฐ ๊ธฐ๋ณธ์ ์ด๊ณ  ํ„ฐ๋ฌด๋‹ˆ์—†๋Š” ํŒ๊ณผ ์กฐ์–ธ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋งŽ์€ C# ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฅผ ์‹คํ–‰์— ์˜ฎ๊ธฐ์ง€ ์•Š๊ณ  ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ดํ•ดํ•˜๋Š” ๋ฐ ์˜ˆ์ƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค์„ธ์š”, ๊ณง ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

ํ•˜์ง€๋งŒ ๋ฌด์—‡๋ณด๋‹ค๋„ ์ด๋Ÿฌํ•œ ํŒ์€ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ๊ทธ ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๋กœ์„œ ์ผ์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ์‹œ๊ฐ„์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒ์ด ๋ฐ”๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค!


๋ ˆ์ฝ”๋“œ ์œ ํ˜• ํ™œ์šฉ



ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•  ๋•Œ C# ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ record ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ํŠนํžˆ ๋ถˆ๋ณ€ ํ‘œํ˜„์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋งค์šฐ ์ฝ๊ธฐ ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์œ ๋ฐฉ๋ฒ•:

//A lot of code lines
public class ApplicationInfo
{
    public string Name { get; init; }
    public string Path { get; init; }
public ApplicationInfo(string name, string path)
    {
        Name = name;
        Path = path;
    }
}


์ข‹์€ ๋ฐฉ๋ฒ•:



//Only one line with record types
public record ApplicationInfo(string name, string path);


์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋งŽ์€ ์ฝ”๋“œ ์ค„์„ ์ €์žฅํ•˜๊ณ  ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช‡ ๋‹ฌ ์•ˆ์— ์šฐ์—ฐํžˆ ๋‹น์‹ ์ด๋‚˜ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ทธ ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ฉด ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๐Ÿ“š์ž์„ธํ•œ ๋‚ด์šฉ์€ Microsoft ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. Create record types


์ž˜๋ชป๋œ ๊ฐœ์ฒด ์ดˆ๊ธฐํ™” ๋ฐฉ์ง€



์ด๊ฒƒ์€ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ฐ„๊ณผํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๊ด€ํ–‰์ž…๋‹ˆ๋‹ค. ์ค‘๊ด„ํ˜ธ ์‚ฌ์ด์— ์†์„ฑ์ด ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ์–ด๋ ค์›Œ์ง€๊ณ  ์ด๋กœ ์ธํ•ด ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋” ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜์œ ๋ฐฉ๋ฒ•:

//Poor code format for reading
Dotnetsafer securityManger = new Dotnetsafer();
securityManger.FindVulnerabilities = true;
securityManger.AppName = "Shield.exe";


์ข‹์€ ๋ฐฉ๋ฒ•:

//Better code format for reading
var securityManger = new Dotnetsafer { 
    FindVulnerabilities = true,
    AppName = "Shield.exe"
};


์ด ๊ฒฝ์šฐ ๋ณด์‹œ๋‹ค์‹œํ”ผ ํ•ด๊ฒฐ์ฑ…์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด ๋ฐ ์ปฌ๋ ‰์…˜ ์ด๋‹ˆ์…œ๋ผ์ด์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“š์ž์„ธํ•œ ๋‚ด์šฉ์€ Microsoft ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. Object and Collection Initializers


Var๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ์ต์ˆ™ํ•ด์ง€๊ธฐ



๊ฐœ๋ฐœ์ž๋Š” ์ข…์ข… ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ๋„ˆ๋ฌด ๊ตฌ์ฒด์ ์ธ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ์„ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ ํ˜ผ๋ž€์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜์œ ๋ฐฉ๋ฒ•:

//Difficult to read
List<Repository.Shield.SecureDependencies> listOfSecureRefs = _repo.Shield.LastDependenciesAnalyzed();


์ข‹์€ ๋ฐฉ๋ฒ•:

//Easier to read
var listOfSecureRefs = _repo.Shield.LastDependenciesAnalyzed();


์ด ๋‚˜์œ ์Šต๊ด€์„ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด var ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒํผ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ตœ์ข… ์ฝ”๋“œ๊ฐ€ ๋” ๊นจ๋—ํ•ด์ง€๊ณ  ์ฝ๊ธฐ๊ฐ€ ํ›จ์”ฌ ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค.

๐Ÿ“š์ž์„ธํ•œ ๋‚ด์šฉ์€ Microsoft ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. Implicitly typed local variables


string.Format() ๋Œ€์‹  ๋ฌธ์ž์—ด ๋ณด๊ฐ„ "$"


String.Format()๋Š” ํ•œ ๋ฌธ์ž์—ด์˜ ๊ฐ’์„ ๋‹ค๋ฅธ ๋ฌธ์ž์—ด์— ์‚ฝ์ž…ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ๊นจ๋—ํ•œ ์ฝ”๋“œ์— ์ดˆ์ ์„ ๋งž์ถ”๋ฉด ๊ฐ€์žฅ ๊นจ๋—ํ•˜๊ฑฐ๋‚˜ ์ตœ๊ณ ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

๋‚˜์œ ๋ฐฉ๋ฒ•:

//using string.Format()
var date = DateTime.Now;
string greetings = string.Format("Today is {0}, the time is {1:HH:mm} now.", date.DayOfWeek, date);


์ข‹์€ ๋ฐฉ๋ฒ•:

//using string interpolation
var date = DateTime.Now;
string greetings = $"Today is {date.DayOfWeek}, the time is {date:HH:mm} now.");


๋ฌธ์ž์—ด ๋ณด๊ฐ„์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๊ณผ ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๋” ์ฝ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋” ๋ณต์žกํ•œ ์‹ค์ œ ์‚ฌ๋ก€์—์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ์ •๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ“š์ž์„ธํ•œ ๋‚ด์šฉ์€ Microsoft ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. $โ€Š-โ€Šstring interpolation


if-else ๋Œ€์‹  Null ๋ณ‘ํ•ฉ(??)



์–ธ๋œป ๋ณด๊ธฐ์— ์ค‘์ฒฉif-else์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด null ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•œ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ต์…˜์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์˜ต์…˜์ด์ง€๋งŒ ์ตœ์„ ์˜ ์˜ต์…˜์€ ์•„๋‹™๋‹ˆ๋‹ค.

๋‚˜์œ ๋ฐฉ๋ฒ•:

if (application != null)
{
    if (application.protected != null)
    {
        return application.protected.shieldLastRun;
    }
    else 
    {
        return string.empty;
    }
}
else
{
    return string.empty;
}


์ข‹์€ ๋ฐฉ๋ฒ•:

return application?.protected?.shieldLastRun ?? string.empty;


null ๋ณ‘ํ•ฉ ์—ฐ์‚ฐ์ž??๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ ์ค„ ์ˆ˜๋ฅผ ํฌ๊ฒŒ ์ค„์ด๊ณ  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“š์ž์„ธํ•œ ๋‚ด์šฉ์€ Microsoft ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ?? andย ??= operators

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ