나는 xml을 읽고 데이터베이스에 데이터를 쓰는 일반 메소드를 작성하려고하는데 문제가있다.결과 형식을 지정하지 않고 C#에서 함수 참조를 전달할 수있는 방법이 있습니까?
이 경우 데이터가 프로그램의 다른 사본에 의해 직렬화되었습니다.
xml의 항목을 SqlParameter에 추가하기 전에 유틸리티 파일의 여러 가지 "고정"방법 중 하나를 통해 해당 항목을 실행해야합니다.
필요한 특정 메서드가 전달되어야하므로 문자열로 전달하고 스위치 구조를 사용하여 리플렉션을 기본 사례로 호출 할 방법을 결정해야합니다.
int, string, bool, decimal, double 또는 DateTime을 반환하도록 지정하지 않고 메서드 참조를 실제로 전달할 방법이 있는지 궁금합니다.
Func을 사용해 보았지만 결과 유형이 필요합니다. 이 유틸리티 기능 모든 매개 변수로 대상을 Tuple<string,Func<?>[] parameters
:
새로운 인수는 아마 같은 것을 보일 것이다.
내 현재 코드 :
private void SaveBundleToTable<T1, T2>
(
string xmlData,
string table,
string storedProcedure,
Tuple<string, string>[] parameters
)
where T1 : DataSet, new()
where T2 : DataRow
{
T1 BundleData = new T1();
BundleData.Clear();
StringReader theReader = new StringReader(xmlDataset);
BundleData.ReadXml(theReader);
foreach (T2 item in BundleData.Tables[table].Rows)
{
SqlCommand _cmd = new SqlCommand(storedProcedure, [SQLConnection]);
_cmd.CommandType = CommandType.StoredProcedure;
foreach (var par in parameters)
{
var _param = getSqlParameter<T2>(item, par.First, par.Second);
_cmd.Parameters.Add(_param);
}
_cmd.ExecuteNonQuery();
}
}
나는 나는 그들이 모두 다를 수 있습니다 목록이없는 것을 제외하고 무엇을 찾고 거의있는 질문을 발견 별도의 방법으로 구조체 전환 :
private SqlParameter getSqlParameter<T>(T item, string columnName, string method) where T : DataRow
{
switch (method)
{
case "FixString":
return new SqlParameter(columnName, util.FixString(item[columnName]));
case "FixInt":
return new SqlParameter(columnName, util.FixInt(item[columnName]));
case "FixBooleanToInt":
return new SqlParameter(columnName, util.FixBooleanToInt(item[columnName]));
case "FixBoolean":
return new SqlParameter(columnName, util.FixBoolean(item[columnName]));
case "FixFloat":
return new SqlParameter(columnName, util.FixFloat(item[columnName]));
case "FixDouble":
return new SqlParameter(columnName, util.FixDouble(item[columnName]));
case "FixDate":
return new SqlParameter(columnName, util.FixDate(item[columnName]));
case "FixDateForZeroTime":
return new SqlParameter(columnName, util.FixDateForZeroTime(item[columnName]));
case "FixDecimal":
return new SqlParameter(columnName, util.FixDecimal(item[columnName]));
default:
try
{
Type thisType = util.GetType();
MethodInfo theMethod = thisType.GetMethod(method);
return new SqlParameter(columnName, theMethod.Invoke(this, new object[]{item[columnName]}));
}
catch (Exception ex)
{
throw new Exception("Unknown utility method: " + method,ex);
}
}
}
편집 1 :
난 그냥Tuple<string,Func<object,dynamic>>
의 매개 변수 유형을 사용하여 시도하고 그것이이 프로젝트는 닷넷 3.5에, 참고로
Tuple<string,?>
의 유형을 판별 할 수 없습니다 말했다로 컴파일하지 않을
그래서 구현 이 질문에 설명 된대로 튜플의 로컬 버전 :
Equivalent of Tuple (.NET 4) for .NET Framework 3.5
편집 2 : 나는 일반적인 방법을 변경 한 경우 그래서 배열을 전달할 수 있습니다
나는 당신이 단지 util.Fix (객체 O를 가지고 있어야 Tuple.New<string, Func<object,decimal>>
fml을 읽는 DataSets는 프로그램에 의해 시행되며 변경할 수 없습니다. – OrangeKing89
Delegate를 대리자 형식으로 항상 사용할 수 있습니다.이 형식은 대리자 형식의 기본 형식이며 일반적으로 서명을 적용하지 않습니다. 어쨌든 당신이 리플렉션을 통해 호출하기 때문에, 나는 당신을 위해 괜찮을 것이라고 기대할 것입니다. –
@PeterDuniho 여기서 반사를 사용하지 않는 것이 좋습니다. switch 문이 정의 된 경우에 메서드를 가지고 있지 않다면 지금은 단지 fallback으로 사용하고 있습니다. – OrangeKing89