Перегруженный метод вызывает перегруженный метод

StackOverflow https://stackoverflow.com/questions/422625

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть метод, который я пишу, который вызывает внутри него другой перегруженный метод. Я хотел бы написать только один внешний метод, так как параметр внешнего метода передается внутреннему. Есть ли способ сделать это?

Я пытался использовать дженерики, но я недостаточно знаю об этом, поэтому он не работает:

public void OuterMethod<T>(T parameter)
{
    InnerMethod(parameter); // InnerMethod accepts an int or a string
}

Я знаю, что могу это сделать:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter);
}

Но я бы предпочел сделать это правильно вместо копирования / вставки кода. Какой лучший способ сделать это?

Это было полезно?

Решение

Вы можете сделать это в C ++, но не в C # (если только внутренний метод не может быть универсальным, а не перегруженным).

<Ч>

В качестве альтернативы (если вы не ответите «нет»), вы можете переключить тип во время выполнения, как, например, ...

public void OuterMethod(object parameter)
{
    if (parameter is int)
        InnerMethod((int)parameter);
    else if (parameter is string)
        InnerMethod((string)parameter);
    else
        throw new SomeKindOfException();
}

... но, очевидно, это проверка во время выполнения, а не проверка во время компиляции.

  

Но я бы предпочел сделать это правильно вместо копирования / вставки кода.

Вы также можете написать программное обеспечение для написания ваших внешних методов (например, используя классы System.CodeDom) вместо того, чтобы писать их вручную, но это, вероятно, больше проблем, чем стоит.

Другие советы

Как сказали другие, вы не можете делать то, что пытаетесь сделать, и вариант, который вы указали в своем вопросе, - лучший выбор.

На самом деле вам придется конвертировать значение, если вы используете универсальный. В противном случае вы можете опускать руки, принимая Объект, как предлагает ChrisW.

 public void OuterMethod<T>(T parameter) 
            {
                T temp = parameter;
                if (temp is string )
                    InnerMethod(Convert.ToString(temp));
                if (temp is int)
                    InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
            }

Вот ссылка на общий обзор: http: // msdn .microsoft.com / EN-US / библиотека / ms172193.aspx

Из вашего описания это выглядит как чрезмерная оптимизация.

Как насчет:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter**.ToString()**);
}

Вы можете использовать тип dynamic, чтобы отложить разрешение перегрузки до времени выполнения.

public void OuterMethod(dynamic parameter)
{
    InnerMethod(parameter);
}

public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }

Предупреждение Выражения типа динамические не разрешены или Тип проверен компилятором. И может быть снижение производительности.

Если OuterMethod всегда вызывает InnerMethod, а InnerMethod принимает только int или строку, то OuterMethod < T > не имеет никакого смысла.

Если only разница в том, что один вызывает InnerMethod (int), а другой вызывает InnerMethod (string), вы можете сделать что-то вроде этого:

public void OuterMethod(string parameter)
{
    InnerMethodA(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethodA(parameter);
}

private void InnerMethodA(object parameter)
{
    // Whatever other implementation stuff goes here

    if (parameter is string)
    {
        InnerMethodB((string) parameter);
    }
    else if (parameter is int)
    {
        InnerMethodB((string) parameter);
    }
    else
    {
        throw new ArgumentException(...);
    }
}

private void InnerMethodB(string parameter)
{
    // ...
}

private void InnerMethodB(int parameter)
{
    // ...
}

Хорошо, у меня похожая ситуация, это метод контроля доступа в моей бизнес-логике.

Существует функция сохранения, которая может быть применена к любому из моих объектов слоя сопротивления.

так это выглядит так

public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
    if(CanWrite(user, entity))
    {
        entity.save();
    }
    else
    {
        throw new Exception("Cannot Save");
    }
}

Как бы то ни было, у меня есть некоторый пользовательский код для определенных сущностей с точки зрения контроля доступа, поэтому я написал следующее, он ищет метод, более подходящий для вопроса, с использованием System.Reflection, &, может ли эта сущность быть написана этот пользователь? "

public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
        {
            int? clubId = null;
            MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
            if(methodInfo != null)
            {
                return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
            }
            else 
            {
                //generic answer
            }
            return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
        }

Теперь каждый раз, когда я добавляю или удаляю метод, мне нужно только добавить или удалить его в одном месте

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top