C #에서 제네릭 메서드 만들기
방법을 일반적인 방법으로 결합하려고합니다. 여러 메소드가 있습니다. 해당하는 쿼리는 올바른 형식이 아닌 경우 null입니다. 모든 유형이 기본적으로 nullable이면 충분하지만 정수 및 날짜에는 nullable입니다.
여기 내가 지금 가지고있는 것입니다. 그러나 숫자 값이 유효하지 않고 불행히도 내 시나리오에서 유효한 값인 경우 0을 다시 전달합니다. 누군가 나를 도울 수 있습니까? 감사합니다!
public static T GetQueryString<T>(string key) where T : IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
기본값 (T)
public static T GetQueryString<T>(string key, T defaultValue) {...}
전화를 더 쉽게 할 수 있습니다.
var intValue = GetQueryString("intParm", Int32.MinValue);
var strValue = GetQueryString("strParm", "");
var dtmValue = GetQueryString("dtmPatm", DateTime.Now); // eg use today's date if not specified
단점은 유효하지 않은 누락 된 쿼리 값을 내기 위해 매직 값이 필요합니다.
알아, 알아,하지만 ...
public static bool TryGetQueryString<T>(string key, out T queryString)
이건 어때? 반환 유형을에서 T
로 변경Nullable<T>
public static Nullable<T> GetQueryString<T>(string key) where T : struct, IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
아마도 모나드를 사용할 수 있습니다. (제이의 대답을 선호하지만)
public class Maybe<T>
{
private readonly T _value;
public Maybe(T value)
{
_value = value;
IsNothing = false;
}
public Maybe()
{
IsNothing = true;
}
public bool IsNothing { get; private set; }
public T Value
{
get
{
if (IsNothing)
{
throw new InvalidOperationException("Value doesn't exist");
}
return _value;
}
}
public override bool Equals(object other)
{
if (IsNothing)
{
return (other == null);
}
if (other == null)
{
return false;
}
return _value.Equals(other);
}
public override int GetHashCode()
{
if (IsNothing)
{
return 0;
}
return _value.GetHashCode();
}
public override string ToString()
{
if (IsNothing)
{
return "";
}
return _value.ToString();
}
public static implicit operator Maybe<T>(T value)
{
return new Maybe<T>(value);
}
public static explicit operator T(Maybe<T> value)
{
return value.Value;
}
}
방법은 다음과 가변합니다.
public static Maybe<T> GetQueryString<T>(string key) where T : IConvertible
{
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
return new Maybe<T>();
}
}
return new Maybe<T>();
}
Convert.ChangeType()
.NET 2.0 BCL에서 nullable 형식 또는 열거 형을 선택 처리하지 않습니다 (하지만 BCL 4.0에서는 수정을 생각합니다). 외부 구현을 더 복잡하게 만드는 대신 변환기가 더 많은 작업을 수행하도록하십시오. 내가 사용하는 구현은 다음과 가변합니다.
public static class Converter
{
public static T ConvertTo<T>(object value)
{
return ConvertTo(value, default(T));
}
public static T ConvertTo<T>(object value, T defaultValue)
{
if (value == DBNull.Value)
{
return defaultValue;
}
return (T) ChangeType(value, typeof(T));
}
public static object ChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
throw new ArgumentNullException("conversionType");
}
// if it's not a nullable type, just pass through the parameters to Convert.ChangeType
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
// null input returns null output regardless of base type
if (value == null)
{
return null;
}
// it's a nullable type, and not null, which means it can be converted to its underlying type,
// so overwrite the passed-in conversion type with this underlying type
conversionType = Nullable.GetUnderlyingType(conversionType);
}
else if (conversionType.IsEnum)
{
// strings require Parse method
if (value is string)
{
return Enum.Parse(conversionType, (string) value);
}
// primitive types can be instantiated using ToObject
else if (value is int || value is uint || value is short || value is ushort ||
value is byte || value is sbyte || value is long || value is ulong)
{
return Enum.ToObject(conversionType, value);
}
else
{
throw new ArgumentException(String.Format("Value cannot be converted to {0} - current type is " +
"not supported for enum conversions.", conversionType.FullName));
}
}
return Convert.ChangeType(value, conversionType);
}
}
그러면 GetQueryString <T> 구현은 다음과 같습니다.
public static T GetQueryString<T>(string key)
{
T result = default(T);
string value = HttpContext.Current.Request.QueryString[key];
if (!String.IsNullOrEmpty(value))
{
try
{
result = Converter.ConvertTo<T>(value);
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
이 클래스 설정 {public int X {get; set;} 공개 문자열 Y {get; 세트; } // 필요에 따라 반복
public settings()
{
this.X = defaultForX;
this.Y = defaultForY;
// repeat ...
}
public void Parse(Uri uri)
{
// parse values from query string.
// if you need to distinguish from default vs. specified, add an appropriate property
}
100 개의 프로젝트에서 잘 작동했습니다. 다른 많은 구문 분석 솔루션 중 하나를 사용하여 값을 구문 분석 할 수 있습니다.
참고 URL : https://stackoverflow.com/questions/2144495/creating-a-generic-method-in-c-sharp
'ProgramingTip' 카테고리의 다른 글
오프라인 설치를 위해 Eclipse 플러그인 업데이트 사이트 다운로드 (0) | 2020.10.27 |
---|---|
“javascript : void (0);” (0) | 2020.10.27 |
TFS : 한 분기에서 로컬로 수행 된 변경 사항을 다른 분기로 출시 (0) | 2020.10.27 |
수동 개입없이 여러 솔루션간에 동일한 Resharper 설정을 공유하는 방법은 무엇입니까? (0) | 2020.10.27 |
컴파일러가 로컬 인증서 변수를 최적화 할 수 있습니까? (0) | 2020.10.27 |