C#에 대해 가장 좋아하는 확장 방법은 무엇입니까? (codeplex.com/extensionoverflow)
당신이 가장 좋아하는 우수한 확장 방법을 게시하는 답변 목록을 만들어 보겠습니다.
요구 사항은 전체 코드와 사용 방법에 대한 예제 및 설명을 게시해야 합니다.
이 주제에 대한 높은 관심을 바탕으로 저는 코데플렉스에 확장 오버플로라는 오픈 소스 프로젝트를 설정했습니다.
코드플렉스 프로젝트에 코드를 넣을 수 있도록 당신의 답변을 승인으로 표시해 주십시오.
링크가 아닌 전체 소스 코드를 게시하십시오.
코데플렉스 뉴스:
24.08.2010 코드플렉스 페이지는 이제 여기에 있습니다. http://extensionoverflow.codeplex.com/
11.11.2008 XmlSerialize / XmlDeserialize가 이제 구현되고 유닛 테스트가 완료되었습니다.
2008년 11월 11일 더 많은 개발자를 위한 여지가 있습니다. ;-) 지금 참여하세요!
11.11.2008 세 번째 기여자가 ExtensionOverflow에 가입했습니다. BKristensen에 오신 것을 환영합니다.
11.11.2008 FormatWith가 구현되고 유닛 테스트가 완료되었습니다.
2008년 11월 09일 두 번째 기여자가 ExtensionOverflow에 가입했습니다.Chakrit에 오신 것을 환영합니다.
2008년 9월 11일 개발자가 더 필요합니다. ;-)
09.11.2008 ThrowIfArgumentIsNull in now 구현 및 Codeplex에서 유닛 테스트.
public static bool In<T>(this T source, params T[] list)
{
if(null==source) throw new ArgumentNullException("source");
return list.Contains(source);
}
대체할 수 있음:
if(reallyLongIntegerVariableName == 1 ||
reallyLongIntegerVariableName == 6 ||
reallyLongIntegerVariableName == 9 ||
reallyLongIntegerVariableName == 11)
{
// do something....
}
and
if(reallyLongStringVariableName == "string1" ||
reallyLongStringVariableName == "string2" ||
reallyLongStringVariableName == "string3")
{
// do something....
}
and
if(reallyLongMethodParameterName == SomeEnum.Value1 ||
reallyLongMethodParameterName == SomeEnum.Value2 ||
reallyLongMethodParameterName == SomeEnum.Value3 ||
reallyLongMethodParameterName == SomeEnum.Value4)
{
// do something....
}
포함:
if(reallyLongIntegerVariableName.In(1,6,9,11))
{
// do something....
}
and
if(reallyLongStringVariableName.In("string1","string2","string3"))
{
// do something....
}
and
if(reallyLongMethodParameterName.In(SomeEnum.Value1, SomeEnum.Value2, SomeEnum.Value3, SomeEnum.Value4)
{
// do something....
}
MiscUtil 프로젝트에는 다양한 확장 방법이 있습니다(전체 소스는 그곳에서 사용할 수 있습니다 - 여기서 반복하지 않겠습니다).내가 가장 좋아하는 것 중 일부는 다른 클래스(예: 범위)와 관련이 있습니다.
날짜 및 시간 관련 - 대부분 단위 테스트용입니다.제가 그것들을 생산에 사용할지 확신할 수 없습니다.
var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();
레인지와 디딤돌 - 이를 가능하게 해준 마크 그라벨의 운영자에게 감사드립니다.
var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());
비교:
var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();
인수 확인:
x.ThrowIfNull("x");
익명 유형(또는 적절한 속성을 가진 다른 유형)에 적용되는 LINQ to XML:
// <Name>Jon</Name><Age>32</Age>
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()
LINQ를 누르면 여기서 설명하는 데 시간이 너무 오래 걸리지만 검색해 보십시오.
string.바로 가기 형식 지정:
public static class StringExtensions
{
// Enable quick and more natural string.Format calls
public static string F(this string s, params object[] args)
{
return string.Format(s, args);
}
}
예:
var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y);
빠른 복사 및 붙여넣기는 여기를 참조하십시오.
타이핑하는 것이 더 자연스럽지 않나요?"some string".F("param")
에 string.Format("some string", "param")
?
보다 읽기 쉬운 이름을 사용하려면 다음 제안 중 하나를 사용하십시오.
s = "Hello {0} world {1}!".Fmt("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow");
s = "Hello {0} world {1}!".Display("Stack", "Overflow");
s = "Hello {0} world {1}!".With("Stack", "Overflow");
..
이것들이 무슨 소용이 있습니까?
public static bool CoinToss(this Random rng)
{
return rng.Next(2) == 0;
}
public static T OneOf<T>(this Random rng, params T[] things)
{
return things[rng.Next(things.Length)];
}
Random rand;
bool luckyDay = rand.CoinToss();
string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!");
public static class ComparableExtensions
{
public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
{
return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
}
}
예:
if (myNumber.Between(3,7))
{
// ....
}
확장 방법:
public static void AddRange<T, S>(this ICollection<T> list, params S[] values)
where S : T
{
foreach (S value in values)
list.Add(value);
}
메소드는 모든 유형에 적용되며 목록에 다양한 항목을 매개 변수로 추가할 수 있습니다.
예:
var list = new List<Int32>();
list.AddRange(5, 4, 8, 4, 2);
반드시 이것을 코드플렉스 프로젝트에 넣으십시오.
개체를 XML로 직렬화/직렬화 해제:
/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
if (xml == null) throw new ArgumentNullException("xml");
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xml))
{
try { return (T)serializer.Deserialize(reader); }
catch { return null; } // Could not be deserialized to this type.
}
}
IE 숫자에 대한 각 항목
public static class FrameworkExtensions
{
// a map function
public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
{
foreach (var item in @enum) mapFunction(item);
}
}
단순한 예:
var buttons = GetListOfButtons() as IEnumerable<Button>;
// click all buttons
buttons.ForEach(b => b.Click());
멋진 예:
// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
.ForEach(item => {
item.Number = 1;
item.Str = "Hello World!";
});
참고:
이것은 그렇지 않습니다.Select
Select
사용자의 함수가 다른 목록으로 변환하는 것을 반환하기를 기대합니다.
각각의 경우 변환/데이터 조작 없이 각 항목에 대해 무언가를 실행할 수 있습니다.
저는 좀 더 기능적인 스타일로 프로그래밍할 수 있도록 이것을 만들었는데, 리스트에는 각각의 경우가 있는 반면 I numberable에는 없다는 것에 놀랐습니다.
이것을 코드플렉스 프로젝트에 넣으십시오.
다음을 수행할 수 있는 내 변환 확장:
int i = myString.To<int>();
TheSoftwareJedi.com 에 게시된 대로 여기 있습니다.
public static T To<T>(this IConvertible obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
public static T ToOrDefault<T>
(this IConvertible obj)
{
try
{
return To<T>(obj);
}
catch
{
return default(T);
}
}
public static bool ToOrDefault<T>
(this IConvertible obj,
out T newObj)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = default(T);
return false;
}
}
public static T ToOrOther<T>
(this IConvertible obj,
T other)
{
try
{
return To<T>obj);
}
catch
{
return other;
}
}
public static bool ToOrOther<T>
(this IConvertible obj,
out T newObj,
T other)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = other;
return false;
}
}
public static T ToOrNull<T>
(this IConvertible obj)
where T : class
{
try
{
return To<T>(obj);
}
catch
{
return null;
}
}
public static bool ToOrNull<T>
(this IConvertible obj,
out T newObj)
where T : class
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = null;
return false;
}
}
실패 시 기본값(공백 생성자 또는 숫자의 경우 "0")을 요청하거나, "기본" 값("기타"라고 함)을 지정하거나, null(여기서 T: 클래스)을 요청할 수 있습니다.또한 사일런트 예외 모델과 수행된 작업을 나타내는 부울을 반환하고 아웃 파라미터가 새 값을 유지하는 일반적인 TryParse 모델을 제공했습니다.그래서 우리의 코드는 이런 것들을 할 수 있습니다.
int i = myString.To<int>();
string a = myInt.ToOrDefault<string>();
//note type inference
DateTime d = myString.ToOrOther(DateTime.MAX_VALUE);
double d;
//note type inference
bool didItGiveDefault = myString.ToOrDefault(out d);
string s = myDateTime.ToOrNull<string>();
Nullable 유형을 전체에 깔끔하게 롤할 수 없었습니다.저는 수건을 던지기 전에 약 20분 동안 시도했습니다.
예외를 기록하기 위한 확장 방법이 있습니다.
public static void Log(this Exception obj)
{
//your logging logic here
}
다음과 같이 사용됩니다.
try
{
//Your stuff here
}
catch(Exception ex)
{
ex.Log();
}
[두 번 게시해서 죄송합니다; 두 번째 것이 더 잘 디자인되었습니다 :-)]
public static class StringExtensions {
/// <summary>
/// Parses a string into an Enum
/// </summary>
/// <typeparam name="T">The type of the Enum</typeparam>
/// <param name="value">String value to parse</param>
/// <returns>The Enum corresponding to the stringExtensions</returns>
public static T EnumParse<T>(this string value) {
return StringExtensions.EnumParse<T>(value, false);
}
public static T EnumParse<T>(this string value, bool ignorecase) {
if (value == null) {
throw new ArgumentNullException("value");
}
value = value.Trim();
if (value.Length == 0) {
throw new ArgumentException("Must specify valid information for parsing in the string.", "value");
}
Type t = typeof(T);
if (!t.IsEnum) {
throw new ArgumentException("Type provided must be an Enum.", "T");
}
return (T)Enum.Parse(t, value, ignorecase);
}
}
문자열을 Enum으로 구문 분석하는 데 유용합니다.
public enum TestEnum
{
Bar,
Test
}
public class Test
{
public void Test()
{
TestEnum foo = "Test".EnumParse<TestEnum>();
}
}
Codeplex 프로젝트에 대한 편집 ---
Scott Dorman에게 코드플렉스 프로젝트에 코드를 게시해도 괜찮겠냐고 물어봤습니다.제가 그에게서 받은 답변은 다음과 같습니다.
SO 포스트와 CodePlex 프로젝트에 대해 알려주셔서 감사합니다.저는 그 질문에 대한 당신의 답변을 지지했습니다.예, 코드는 현재 CodeProject OpenLicense(http://www.codeproject.com/info/cpol10.aspx) 의 퍼블릭 도메인에 유효합니다.
나는 이것이 CodePlex 프로젝트에 포함되는 것에 문제가 없으며, 만약 당신이 나를 프로젝트에 추가하고 싶다면 나는 그 방법과 몇 가지 추가적인 열거형 도우미 방법을 추가할 것입니다.
저는 이것이 꽤 유용하다고 생각합니다.
public static class PaulaBean
{
private static String paula = "Brillant";
public static String GetPaula<T>(this T obj) {
return paula;
}
}
CodePlex에서 사용할 수 있습니다.
예:
DateTime firstDayOfMonth = DateTime.Now.First();
DateTime lastdayOfMonth = DateTime.Now.Last();
DateTime lastFridayInMonth = DateTime.Now.Last(DayOfWeek.Friday);
DateTime nextFriday = DateTime.Now.Next(DayOfWeek.Friday);
DateTime lunchTime = DateTime.Now.SetTime(11, 30);
DateTime noonOnFriday = DateTime.Now.Next(DayOfWeek.Friday).Noon();
DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight();
gitorious.org/cadenza 은 제가 본 것 중 가장 유용한 확장 방법의 완전한 라이브러리입니다.
여기 제가 프레젠테이션 포맷에 자주 사용하는 것이 있습니다.
public static string ToTitleCase(this string mText)
{
if (mText == null) return mText;
System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Globalization.TextInfo textInfo = cultureInfo.TextInfo;
// TextInfo.ToTitleCase only operates on the string if is all lower case, otherwise it returns the string unchanged.
return textInfo.ToTitleCase(mText.ToLower());
}
여기 로마 숫자의 앞뒤가 있습니다.자주 사용되지는 않지만 유용할 수 있습니다.용도:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
출처:
public static class RomanNumeralExtensions
{
private const int NumberOfRomanNumeralMaps = 13;
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "M", 1000 },
{ "CM", 900 },
{ "D", 500 },
{ "CD", 400 },
{ "C", 100 },
{ "XC", 90 },
{ "L", 50 },
{ "XL", 40 },
{ "X", 10 },
{ "IX", 9 },
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
크기를 처리하는 편리한 방법:
public static class Extensions {
public static int K(this int value) {
return value * 1024;
}
public static int M(this int value) {
return value * 1024 * 1024;
}
}
public class Program {
public void Main() {
WSHttpContextBinding serviceMultipleTokenBinding = new WSHttpContextBinding() {
MaxBufferPoolSize = 2.M(), // instead of 2097152
MaxReceivedMessageSize = 64.K(), // instead of 65536
};
}
}
Winform 컨트롤의 경우:
/// <summary>
/// Returns whether the function is being executed during design time in Visual Studio.
/// </summary>
public static bool IsDesignTime(this Control control)
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
if (control.Site != null && control.Site.DesignMode)
{
return true;
}
var parent = control.Parent;
while (parent != null)
{
if (parent.Site != null && parent.Site.DesignMode)
{
return true;
}
parent = parent.Parent;
}
return false;
}
/// <summary>
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// </summary>
public static void SetDropDownWidth(this ComboBox comboBox)
{
var g = comboBox.CreateGraphics();
var font = comboBox.Font;
float maxWidth = 0;
foreach (var item in comboBox.Items)
{
maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width);
}
if (comboBox.Items.Count > comboBox.MaxDropDownItems)
{
maxWidth += SystemInformation.VerticalScrollBarWidth;
}
comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth));
}
설계 시간 사용 여부:
public class SomeForm : Form
{
public SomeForm()
{
InitializeComponent();
if (this.IsDesignTime())
{
return;
}
// Do something that makes the visual studio crash or hang if we're in design time,
// but any other time executes just fine
}
}
드롭다운 폭 사용 설정:
ComboBox cbo = new ComboBox { Width = 50 };
cbo.Items.Add("Short");
cbo.Items.Add("A little longer");
cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?");
cbo.SetDropDownWidth();
언급하는 것을 잊었습니다. 언제든지 이것들을 코데플렉스에서 사용하세요...
ThrowIfArgumentIsNull은 우리 모두가 수행해야 하는 Null 검사를 수행하는 좋은 방법입니다.
public static class Extensions
{
public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
{
if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
}
}
다음은 사용 방법이며 네임스페이스 내의 모든 클래스 또는 네임스페이스 내의 모든 클래스에서 작동합니다.
internal class Test
{
public Test(string input1)
{
input1.ThrowIfArgumentIsNull("input1");
}
}
CodePlex 프로젝트에서 이 코드를 사용해도 됩니다.
C#로 이동할 때 Visual Basic's With 문이 그리워서 다음과 같습니다.
public static void With<T>(this T obj, Action<T> act) { act(obj); }
C#에서 사용하는 방법은 다음과 같습니다.
someVeryVeryLonggggVariableName.With(x => {
x.Int = 123;
x.Str = "Hello";
x.Str2 = " World!";
});
타이핑을 많이 절약합니다!
이를 다음과 비교:
someVeryVeryLonggggVariableName.Int = 123;
someVeryVeryLonggggVariableName.Str = "Hello";
someVeryVeryLonggggVariableName.Str2 = " World!";
코드플렉스 프로젝트에 투입
camelCaseWord 또는 PascalCaseWord를 사용하여 단어화(즉, camelCaseWord => camelCaseWord)
public static string Wordify( this string camelCaseWord )
{
// if the word is all upper, just return it
if( !Regex.IsMatch( camelCaseWord, "[a-z]" ) )
return camelCaseWord;
return string.Join( " ", Regex.Split( camelCaseWord, @"(?<!^)(?=[A-Z])" ) );
}
Capitalize와 함께 사용하는 경우가 많습니다.
public static string Capitalize( this string word )
{
return word[0].ToString( ).ToUpper( ) + word.Substring( 1 );
}
사용 예
SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id );
List<PropertyInfo> properties = entity.GetType().GetPublicNonCollectionProperties( );
// wordify the property names to act as column headers for an html table or something
List<string> columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( );
코드플렉스 프로젝트에서 무료로 사용 가능
이것이 도움이 된다는 것을 알았습니다.
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
return pSeq ?? Enumerable.Empty<T>();
}
호출 코드에서 null 검사를 제거합니다.이제 할 수 있습니다.
MyList.EmptyIfNull().Where(....)
지정된 culture를 사용하여 형식이 지정된 문자열로 이중 변환:
public static class ExtensionMethods
{
public static string ToCurrency(this double value, string cultureName)
{
CultureInfo currentCulture = new CultureInfo(cultureName);
return (string.Format(currentCulture, "{0:C}", value));
}
}
예:
double test = 154.20;
string testString = test.ToCurrency("en-US"); // $154.20
다음은 Rick Strahl의 코드(및 주석)를 조정하여 바이트 배열 또는 텍스트 파일을 문자열로 변환할 때마다 바이트 순서 표시를 추측하거나 읽을 필요가 없도록 하는 확장 방법입니다.
이 스니펫을 사용하면 다음 작업을 간단히 수행할 수 있습니다.
byte[] buffer = File.ReadAllBytes(@"C:\file.txt");
string content = buffer.GetString();
버그가 발견되면 댓글에 추가해주세요.코데플렉스 프로젝트에 자유롭게 포함시키세요.
public static class Extensions
{
/// <summary>
/// Converts a byte array to a string, using its byte order mark to convert it to the right encoding.
/// Original article: http://www.west-wind.com/WebLog/posts/197245.aspx
/// </summary>
/// <param name="buffer">An array of bytes to convert</param>
/// <returns>The byte as a string.</returns>
public static string GetString(this byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
return "";
// Ansi as default
Encoding encoding = Encoding.Default;
/*
EF BB BF UTF-8
FF FE UTF-16 little endian
FE FF UTF-16 big endian
FF FE 00 00 UTF-32, little endian
00 00 FE FF UTF-32, big-endian
*/
if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
encoding = Encoding.UTF8;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.Unicode;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.BigEndianUnicode; // utf-16be
else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
encoding = Encoding.UTF32;
else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
encoding = Encoding.UTF7;
using (MemoryStream stream = new MemoryStream())
{
stream.Write(buffer, 0, buffer.Length);
stream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream, encoding))
{
return reader.ReadToEnd();
}
}
}
}
이것은 제가 오늘 만든 것입니다.
// requires .NET 4
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue = default(TReturn)) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
// versions for CLR 2, which doesn't support optional params
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
where TIn : class
{ return obj != null ? func(obj) : default(TReturn); }
이를 통해 다음을 수행할 수 있습니다.
var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());
이것보다 더 유창하고 읽기 쉬운 (IMO):
var lname = (thingy != null ? thingy.Name : null) != null
? thingy.Name.ToLower() : null;
"코드플렉스 프로젝트에 코드를 넣을 수 있도록 답변을 표시해 주십시오."
왜죠? 이 사이트의 모든 자료는 CC-by-sa-2.5로 되어 있습니다. 그러니, 당신의 확장 오버플로 프로젝트를 동일한 라이선스 하에 두면 당신은 그것을 자유롭게 사용할 수 있습니다.
어쨌든, 여기 String이 있습니다.이 질문에 기반한 역함수입니다.
/// <summary>
/// Reverse a String
/// </summary>
/// <param name="input">The string to Reverse</param>
/// <returns>The reversed String</returns>
public static string Reverse(this string input)
{
char[] array = input.ToCharArray();
Array.Reverse(array);
return new string(array);
}
MySqlDataReader에서 값을 가져오는 동안 지루한 null 검사에 싫증이 나서 다음과 같이 처리했습니다.
public static DateTime? GetNullableDateTime(this MySqlDataReader dr, string fieldName)
{
DateTime? nullDate = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullDate : dr.GetDateTime(fieldName);
}
public static string GetNullableString(this MySqlDataReader dr, string fieldName)
{
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? String.Empty : dr.GetString(fieldName);
}
public static char? GetNullableChar(this MySqlDataReader dr, string fieldName)
{
char? nullChar = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullChar : dr.GetChar(fieldName);
}
물론 모든 SqlDataReader에서 사용할 수 있습니다.
행기와 조 모두 이를 수행하는 방법에 대해 좋은 의견을 제시했으며, 그 이후로 저는 다른 맥락에서 비슷한 것을 구현할 수 있는 기회를 가졌습니다. 그래서 여기 다른 버전이 있습니다.
public static int? GetNullableInt32(this IDataRecord dr, int ordinal)
{
int? nullInt = null;
return dr.IsDBNull(ordinal) ? nullInt : dr.GetInt32(ordinal);
}
public static int? GetNullableInt32(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableInt32(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, int ordinal)
{
bool? nullBool = null;
return dr.IsDBNull(ordinal) ? nullBool : dr.GetBoolean(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableBoolean(ordinal);
}
LINQ가 인수로 I Compomparer를 구현하는 클래스를 수강하는 OrderBy를 제공하지만 단순한 익명 비교 함수를 전달하는 것을 지원하지 않는 것이 화가 났습니다.고쳤어요.
이 클래스는 비교기 함수에서 I 비교기를 만듭니다...
/// <summary>
/// Creates an <see cref="IComparer{T}"/> instance for the given
/// delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
public static IComparer<T> Create(Func<T, T, int> comparison)
{
return new ComparerFactory<T>(comparison);
}
private readonly Func<T, T, int> _comparison;
private ComparerFactory(Func<T, T, int> comparison)
{
_comparison = comparison;
}
#region IComparer<T> Members
public int Compare(T x, T y)
{
return _comparison(x, y);
}
#endregion
}
...이러한 확장 메서드는 열거형에 대한 새로운 OrderBy 오버로드를 표시합니다.LINQ에서 SQL로 이 작업이 가능한지는 의문이지만 LINQ에서 객체로 작업하는 경우에는 적합합니다.
public static class EnumerableExtensions
{
/// <summary>
/// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderBy(keySelector, comparer);
}
/// <summary>
/// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderByDescending(keySelector, comparer);
}
}
원한다면 코드플렉스에 올려도 좋습니다.
이것은 MVC를 위한 것으로, 그것은 생성하는 기능을 추가합니다.<label />
에 태그를 달다.Html
사용 가능한 변수:ViewPage
유사한 확장 기능을 개발하려는 다른 사람들에게 유용하기를 바랍니다.
사용:
<%= Html.Label("LabelId", "ForId", "Text")%>
출력:
<label id="LabelId" for="ForId">Text</label>
코드:
public static class HtmlHelperExtensions
{
public static string Label(this HtmlHelper Html, string @for, string text)
{
return Html.Label(null, @for, text);
}
public static string Label(this HtmlHelper Html, string @for, string text, object htmlAttributes)
{
return Html.Label(null, @for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string @for, string text, IDictionary<string, object> htmlAttributes)
{
return Html.Label(null, @for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string id, string @for, string text)
{
return Html.Label(id, @for, text, null);
}
public static string Label(this HtmlHelper Html, string id, string @for, string text, object htmlAttributes)
{
return Html.Label(id, @for, text, new RouteValueDictionary(htmlAttributes));
}
public static string Label(this HtmlHelper Html, string id, string @for, string text, IDictionary<string, object> htmlAttributes)
{
TagBuilder tag = new TagBuilder("label");
tag.MergeAttributes(htmlAttributes);
if (!string.IsNullOrEmpty(id))
tag.MergeAttribute("id", Html.AttributeEncode(id));
tag.MergeAttribute("for", Html.AttributeEncode(@for));
tag.SetInnerText(Html.Encode(text));
return tag.ToString(TagRenderMode.Normal);
}
}
회전:
DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT @param";
DbParameter param = command.CreateParameter();
param.ParameterName = "@param";
param.Value = "Hello World";
command.Parameters.Add(param);
여기에:
DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World");
다음 확장 방법 사용:
using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;
namespace DbExtensions {
public static class Db {
static readonly Func<DbConnection, DbProviderFactory> getDbProviderFactory;
static readonly Func<DbCommandBuilder, int, string> getParameterName;
static readonly Func<DbCommandBuilder, int, string> getParameterPlaceholder;
static Db() {
getDbProviderFactory = (Func<DbConnection, DbProviderFactory>)Delegate.CreateDelegate(typeof(Func<DbConnection, DbProviderFactory>), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
getParameterName = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
getParameterPlaceholder = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
}
public static DbProviderFactory GetProviderFactory(this DbConnection connection) {
return getDbProviderFactory(connection);
}
public static DbCommand CreateCommand(this DbConnection connection, string commandText, params object[] parameters) {
if (connection == null) throw new ArgumentNullException("connection");
return CreateCommandImpl(GetProviderFactory(connection).CreateCommandBuilder(), connection.CreateCommand(), commandText, parameters);
}
private static DbCommand CreateCommandImpl(DbCommandBuilder commandBuilder, DbCommand command, string commandText, params object[] parameters) {
if (commandBuilder == null) throw new ArgumentNullException("commandBuilder");
if (command == null) throw new ArgumentNullException("command");
if (commandText == null) throw new ArgumentNullException("commandText");
if (parameters == null || parameters.Length == 0) {
command.CommandText = commandText;
return command;
}
object[] paramPlaceholders = new object[parameters.Length];
for (int i = 0; i < paramPlaceholders.Length; i++) {
DbParameter dbParam = command.CreateParameter();
dbParam.ParameterName = getParameterName(commandBuilder, i);
dbParam.Value = parameters[i] ?? DBNull.Value;
command.Parameters.Add(dbParam);
paramPlaceholders[i] = getParameterPlaceholder(commandBuilder, i);
}
command.CommandText = String.Format(CultureInfo.InvariantCulture, commandText, paramPlaceholders);
return command;
}
}
}
ADO.NET 확장 메서드 추가: DB 확장
언급URL : https://stackoverflow.com/questions/271398/what-are-your-favorite-extension-methods-for-c-codeplex-com-extensionoverflow
'programing' 카테고리의 다른 글
Tuple을 에서 사용할 수 있는 실용적인 예입니다.넷 4.0? (0) | 2023.05.18 |
---|---|
Git: "손상된 느슨한 개체" (0) | 2023.05.18 |
데이터가 Null입니다.이 메서드 또는 속성은 Null 값에 대해 호출할 수 없습니다. (0) | 2023.05.18 |
Objective-C의 메서드 구문 (0) | 2023.05.18 |
Xcode: 빌드 실패, 오류 메시지 없음 (0) | 2023.05.18 |