에게 연장을 사용하여 일반적인 유형의 리더를 만들려고 passing static reflection information to static generic methods이 질문에 반사
임 내가 클래스를 사용하여 데이터 액세스를 많이 할 같은 일반 유형 리더를 만들려고하고 난 매우 일반적인 방법을 만들려고 해요 많은 코드없이 데이터를 읽을 수 있습니다. 이
public static T Read<T>(string field,IDataRecord data)
{
Type type1 = typeof (T);
try
{
if (type1 == typeof(String))
{
return (T)Convert.ChangeType(readString(data[field].ToString()), typeof(T));
}
if (type1 == typeof(int?))
{
return (T)Convert.ChangeType(readIntN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(Guid?))
{
return (T)Convert.ChangeType(readGuidN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(double?))
{
return (T)Convert.ChangeType(readDoubleN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(decimal?))
{
var res = readDecimalN(data[field].ToString());
return (T)Convert.ChangeType(res, typeof(T));
}
if (type1 == typeof(float?))
{
return (T)Convert.ChangeType(readFloatN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(bool?))
{
return (T)Convert.ChangeType(readBoolN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(DateTime?))
{
return (T)Convert.ChangeType(readDatetimeN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(int))
{
return (T)Convert.ChangeType(readInt(data[field].ToString()), typeof(T));
}
if (type1 == typeof(long?))
{
return (T)Convert.ChangeType(readLongN(data[field].ToString()), typeof(T));
}
if (type1 == typeof(long))
{
return (T)Convert.ChangeType(readLong(data[field].ToString()), typeof(T));
}
if (type1 == typeof(Guid))
{
return (T)Convert.ChangeType(readGuid(data[field].ToString()), typeof(T));
}
if (type1 == typeof(double))
{
return (T)Convert.ChangeType(readDouble(data[field].ToString()), typeof(T));
}
if (type1 == typeof(decimal))
{
return (T)Convert.ChangeType(readDecimal(data[field].ToString()), typeof(T));
}
if (type1 == typeof(float) || type1 == typeof(Single))
{
return (T)Convert.ChangeType(readFloat(data[field].ToString()), typeof(T));
}
if (type1 == typeof(bool))
{
return (T)Convert.ChangeType(readBool(data[field].ToString()), typeof(T));
}
if (type1 == typeof(DateTime))
{
return (T)Convert.ChangeType(readDatetime(data[field].ToString()), typeof(T));
}
}
catch (Exception)
{
throw;
}
throw new Exception(String.Format("Data Type Not Supported: {0}", type1));
}
그러나 이것은 잘못된 캐스트 예외를 던지고있다처럼
읽기의 대부분을 수행하는 코드의 일부가 보인다.
readXXX 방법
는 문제가 리턴 각 문에 발생하는되어 잘 작동하는나는 또한
public static T SafeConvert<T>(string s, T defaultValue)
{
if (string.IsNullOrEmpty(s))
return defaultValue;
return (T)Convert.ChangeType(s, typeof(T));
}
를 사용하여 시도했지만 여전히 실패
편집 :
메소드 호출 중
private static List<T> GetItems<T>(IDataReader reader)
{
var items = new List<T>();
while (reader.Read())
{
Type type1 = typeof (T);
var item = (T) Activator.CreateInstance(typeof (T), new object[] {});
foreach (PropertyInfo info in type1.GetProperties())
{
int written = 0;
if (info.CanWrite)
{
#region
try
{
Type dataType = info.PropertyType;
MethodInfo method = typeof (DataReader).GetMethod("Read",BindingFlags.Static | BindingFlags.Public);
MethodInfo generic = method.MakeGenericMethod(dataType);
var t = generic.Invoke(null, new object[] {info.Name, reader});
info.SetValue(item, t);
더 많이 ...
사람들은 내가이를 사용할 것을 요구하는 것, 그리고 궁극적으로는 한 줄에있는 파일의 위치를 전달하여이 CSV 또는 SQL 될 모든 소스에서 읽도록를 IEnumerable을 만들 날 수 있습니다 또는 SQL 쿼리 즉
//returns Ienumerable<MyClass>
var list = Reader.ReadSql<MyClass>(DataBases.Test,"select * from TestTable where someAttribute = 1");
// also returns Ienumerable MyClass
var list2 = Readre.ReadCsv<MyClass>(@"c:\file1.csv",",");
내가 지금 실행해야하지만이 경우 데이터 유형 긴 목록의 repetiiton이 필요 == 대해서 typeof 내가 하나의 일반적인 읽기 방법으로 그 리팩토링 기대 된 각 구현 (문자열) 만입니다 변환에 문제가있다
* 많은 * 코드를 게시했지만 메소드를 호출하는 방법이나 값이 무엇인지를 보여주지 않았습니다. 그것은 당신을 도우려는 것을 매우 어렵게 만듭니다. 또한 try/catch 블록은 무의미합니다. 원래 예외를 다시 던지면됩니다. –
당신은 말하지 않았지만 IConvertable을 구현하지 않는 Guid와 같은 유형에서는 예외가 발생한다고 추측합니다. 이러한 유형의 생성자를 호출해야합니다. –
안녕 존 전화가 상단에 링크로 이전 질문에서 만들어진, 나는이 질문에 대한 자세한 내용을 추가 할 것입니다 (예, 나는 잡기 시도가 현재 디버깅을 위해 불필요하다는 것을 알고 있습니다) – RoughPlace