Вот правильный ответ, извлеченный из комментариев Даниэля Риковского и Псейдемана. Я устала от того, что надо проползать через комментарии, чтобы найти правильный ответ ...
Если вы используете Rails (ActiveSupport):
result.class.name.demodulize
Если вы используете POR (plain-ol-Ruby):
result.class.name.split('::').last
Конечно. Просто определите делегат следующим образом:
public delegate bool GetUsername(string clientID, out string username);
А затем передайте его в свою функцию и вызовите:
private static bool TryGetLogonUserId(IGetClientUsername clientController, string sClientId, out int? logonUserId, GetUsername func)
{
string username;
if (func.Invoke(sClientId, out username))
{
// ... snip common code ...
}
return false;
}
Чтобы вызвать функцию с делегатом, сделайте следующее:
TryGetLogonUserId(/* first params... */, clientController.GetClientUsername);
Хотя вы можете передать делегат в качестве параметра, я предлагаю использовать другой маршрут. Инкапсулируйте тело оператора if
, который включает общий код в другой функции, и вызовите его в обеих функциях.
Visual Studio имеет функцию «Refactor ->
Extract Method» в контекстное меню. Вы можете просто заполнить одно из тел, выбрать тело и использовать эту функцию для автоматического извлечения из него метода.
Тип функции записывается как Func
void TryGetLogon(Func<IGetClientUsername, string, out int?, bool> f) {
// ...
f(x, y, z, a);
}
// ...
TryGetLogon(TryGetLogonUserIdByGraphicalUsername);
Как насчет простой передачи логического флага?
private static bool TryGetLogonUserIdByUsername(
IGetClientUsername clientController,
string sClientId, out int? logonUserId, bool graphical)
{
string username;
bool gotClient = false;
if (graphical)
{
gotClient = clientController.GetClientGraphicalUsername(
sClientId, out username);
}
else
{
gotClient = clientController.GetClientUsername(
sClientId, out username);
}
if (gotClient)
{
// ... snip common code ...
}
return false;
}
Вы можете передать MethodInfo , который можно найти статически. Однако я согласен с тем, что может потребоваться редизайн.
private static readonly MethodInfo getRegularLogin = typeof(IGetClientUsername).GetMethod("GetClientUsername");
private static bool TryGetLogonUserIdByUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
{
string username;
return TryGetLoginReflective(getRegularLogin, clientController, sClientId, out username, out logonUserId);
}
private static readonly MethodInfo getGraphicalLogin = typeof(IGetClientUsername).GetMethod("GetClientGraphicalUsername");
private static bool TryGetLogonUserIdByGraphicalUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
{
string username;
return TryGetLoginReflective(getGraphicalLogin, clientController, sClientId, out username, out logonUserId);
}
private static bool TryGetLoginReflective(MethodInfo method, IGetClientUsername clientController, string sClientId, out string username, out int? logonUserId)
{
object[] args = new object[]{sClientId, null};
if((bool)method.Invoke(clientController, args))
{
// ... snip common code ...
}
logonUserId = ...;
username = (string)args[1];
return false;
}