좋은 확장 기능 설계
모범 사례를 적용하고 함정을 피합니다.
좋은 확장 기능 설계은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
사랑받는 확장 메서드 설계하기
확장 메서드는 강력하지만, 강력한 기능은 잘못 사용되기 쉽습니다. 좋은 확장 메서드는 해당 형식의 자연스러운 일부처럼 느껴지고, 쉽게 찾을 수 있으며, 호출자를 당황하게 하지 않습니다. 이 단원에서는 실용적인 지침을 다룹니다.
정체성이 아닌 동작 확장하기
파이프라인에서 읽기 좋은 유틸리티 동작에는 확장 메서드를 사용하는 것이 좋습니다. 메서드가 실제로 여러분이 소유한 형식에 속한다면 대신 진짜 멤버로 만드십시오.
using System;
public static class TimeExtensions
{
// A pleasant, focused helper
public static bool IsWeekend(this DayOfWeek day)
=> day == DayOfWeek.Saturday || day == DayOfWeek.Sunday;
}
public class Program
{
public static void Main()
{
Console.WriteLine(DayOfWeek.Sunday.IsWeekend());
Console.WriteLine(DayOfWeek.Monday.IsWeekend());
}
}가능하면 메서드를 순수하게 유지하기
새 값을 반환하고 부수 효과를 일으키지 않는 확장 메서드는 동작을 이해하고 연결하기가 가장 쉽습니다. 입력을 받아 값을 반환하는 형태를 목표로 하십시오.
using System;
public static class StringExtensions
{
// Pure: depends only on input, returns a new string
public static string Truncate(this string s, int max)
=> s.Length <= max ? s : s.Substring(0, max) + "...";
}
public class Program
{
public static void Main()
{
Console.WriteLine("Extension methods are great".Truncate(10));
}
}null 입력 방어하기
호출자는 null 수신 객체에서도 확장 메서드를 호출할 수 있으므로 어떤 동작을 할지 신중하게 결정하십시오. null을 정상적으로 처리하거나 명확한 ArgumentNullException을 발생시키십시오.
using System;
public static class StringExtensions
{
public static string SafeUpper(this string s)
{
if (s is null) throw new ArgumentNullException(nameof(s));
return s.ToUpper();
}
}
public class Program
{
public static void Main()
{
try { ((string)null).SafeUpper(); }
catch (ArgumentNullException ex) { Console.WriteLine("Caught: " + ex.ParamName); }
Console.WriteLine("ok".SafeUpper());
}
}찾기 쉬운 이름 사용하기
개발자는 점을 입력한 후 IntelliSense의 목록을 살펴보며 확장 메서드를 찾습니다. 결과를 설명하는 명확한 동사 중심의 이름을 사용하면 도우미를 쉽게 찾을 수 있고 자체적으로 문서 역할도 하게 됩니다.
using System;
using System.Collections.Generic;
public static class CollectionExtensions
{
public static bool HasItems<T>(this ICollection<T> c)
=> c != null && c.Count > 0;
}
public class Program
{
public static void Main()
{
var list = new List<int> { 1 };
Console.WriteLine(list.HasItems());
}
}관련 확장 메서드를 일관되게 그룹화하기
하나의 개념에 속하는 확장 메서드는 이름을 잘 지은 하나의 정적 클래스와 네임스페이스에 배치하십시오. 이렇게 하면 가져오기의 의미가 분명해지고 사용자가 원하는 도우미만 정확히 가져올 수 있습니다.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static IEnumerable<T> TakeFirst<T>(this IEnumerable<T> source, int n)
{
int taken = 0;
foreach (var item in source)
{
if (taken++ >= n) yield break;
yield return item;
}
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3, 4 };
Console.WriteLine(string.Join(",", nums.TakeFirst(2)));
}
}예상 밖의 동작 숨기지 않기
간단해 보이지만 비용이 많이 들거나 상태를 변경하는 작업을 수행하는 확장 메서드는 기대를 저버립니다. 비용이 드는 동작은 이름만 보고도 알 수 있게 하십시오. 데이터베이스를 조회하거나 상태를 변경한다면 그에 맞는 이름을 사용하십시오.
using System;
public static class MathExtensions
{
// Cheap and obvious: no hidden cost
public static int ClampMin(this int value, int min)
=> value < min ? min : value;
}
public class Program
{
public static void Main()
{
Console.WriteLine((-3).ClampMin(0));
Console.WriteLine(5.ClampMin(0));
}
}object 확장 피하기
object를 확장하면 프로그램의 모든 형식에 메서드가 추가되어 IntelliSense가 어디서나 복잡해집니다. 대신 의미에 맞는 가장 구체적인 형식이나 인터페이스를 대상으로 하십시오.
using System;
public static class IntExtensions
{
// Specific to int, not object - far less noisy
public static string ToOrdinal(this int n)
{
if (n % 10 == 1 && n % 100 != 11) return n + "st";
if (n % 10 == 2 && n % 100 != 12) return n + "nd";
if (n % 10 == 3 && n % 100 != 13) return n + "rd";
return n + "th";
}
}
public class Program
{
public static void Main()
{
Console.WriteLine(1.ToOrdinal());
Console.WriteLine(22.ToOrdinal());
}
}시퀀스에는 IEnumerable 반환 우선하기
시퀀스 연산자에서는 IEnumerable<T>를 반환하고 지연 실행을 사용하십시오. 이렇게 하면 조합하기 좋고, 호출자가 필요로 하지 않을 수도 있는 데이터를 강제로 구체화하지 않아도 됩니다.
using System;
using System.Collections.Generic;
public static class SeqExtensions
{
public static IEnumerable<int> Doubled(this IEnumerable<int> source)
{
foreach (var n in source) yield return n * 2;
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3 };
foreach (var n in nums.Doubled()) Console.WriteLine(n);
}
}좋은 확장 메서드 점검 목록
확장 메서드를 배포하기 전에 다음을 물어보십시오. 이름이 명확한가? 순수한가, 아니면 부수 효과가 분명한가? null을 처리하는가? 대상 형식이 구체적인가? 합리적으로 그룹화되어 있는가? 모두 그렇다면 다른 사람들이 즐겁게 사용할 수 있는 도우미를 만든 것입니다.
using System;
public static class StringExtensions
{
public static string OrDefault(this string s, string fallback)
=> string.IsNullOrEmpty(s) ? fallback : s;
}
public class Program
{
public static void Main()
{
Console.WriteLine("".OrDefault("N/A"));
Console.WriteLine("value".OrDefault("N/A"));
}
}직접 해 보기
점검 목록을 적용해 보십시오. 구체적인 대상 형식, 명확한 이름, null 허용, 순수한 결과를 사용합니다. 이 작은 확장 메서드는 모든 지침을 충족합니다.
using System;
using System.Collections.Generic;
public static class DictionaryExtensions
{
// Clear name, specific type, null-safe, pure
public static TValue GetOrDefault<TKey, TValue>(
this IReadOnlyDictionary<TKey, TValue> dict, TKey key, TValue fallback)
{
if (dict == null) return fallback;
return dict.TryGetValue(key, out var value) ? value : fallback;
}
}
public class Program
{
public static void Main()
{
var ages = new Dictionary<string, int> { ["Ann"] = 30 };
Console.WriteLine(ages.GetOrDefault("Ann", -1));
Console.WriteLine(ages.GetOrDefault("Bob", -1));
}
}빠른 확인
설계 지침을 적용해 보십시오.
요약
잘 설계된 확장 메서드는 해당 형식에 자연스럽게 어울리고 예측 가능하게 동작합니다.
- 잘 연결되고 값을 반환하는 순수한 도우미를 우선하십시오.
- null 동작을 결정하고 문서화하십시오.
- 찾기 쉽도록 명확한 동사 중심의 이름을 사용하십시오.
object가 아니라 구체적인 형식이나 인터페이스를 대상으로 하십시오.- 관련 도우미를 그룹화하고 시퀀스에는
IEnumerable<T>를 반환하십시오.
AI 튜터와 함께 C#을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 93
- 레슨
- 346
자주 묻는 질문
“좋은 확장 기능 설계” 강의는 무료인가요?
네 — “좋은 확장 기능 설계” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“좋은 확장 기능 설계”에서 뭘 배우나요?
모범 사례를 적용하고 함정을 피합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C# Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“좋은 확장 기능 설계” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 확장 메서드 정의
- 인터페이스와 제네릭 확장
- 확장 메서드 확인 과정
- 좋은 확장 기능 설계