Доступ к внутреннему методу в запечатанном классе C#

Я пытаюсь получить доступ к внутреннему методу в запечатанном классе, но, поскольку это запечатанный класс, я не могу унаследовать внутренний метод. Бэкэнд-часть решения, над которым я работаю, разработана таким образом.

Я нашел обходной путь для этого, который использует расширение класса

public static class LocalizationsManagerExtension
{
    public static string AddAppUserBasic(this LocalizationsManager objDotnet, AppUser newUser, string pword)
    {
        try
        {
            objDotnet.AddAppUserBasic(newUser, pword);
            return "Success!";
        }
        catch(Exception ex)
        {
            return ex.Message;
        }
        //return IdentityResult.Success;
        //return System.Threading.Tasks.Task.Run();
        //return "Welcome to the World of DotNet....Mr. " + password;
    }
}

 public ActionResult UserAddNew(UserAddNewModel model)
    {
        if (ModelState.IsValid)
        {

            var user = new DataAccess.AppUser();
            user.Name = model.username;
            user.Password = model.password;
            user.DeveloperRole = model.isDeveloperRole;
            user.AdministratorRole = model.isAdministratorRole;
            user.TranslatorRole = model.isTranslatorRole;
            user.IsDomainUser = model.IsDomainUser;
            user.ManagerRole = model.isManagerRole;
            user.State = Data.Framework.Repository.Helpers.ObjectState.Added;

            var result = LM.AddAppUserBasic(user, user.Password);
            if (result == "Success!")
            {
                ViewBag.ReturnUrl = "/Usermanagement/UserLogin";
                //return RedirectToAction("UserLogin", "UserManagement");
            }
            else {  }
        }


        // If we got this far, something failed, redisplay form
        return View(model);
    }

Я попробовал это, но не повезло. Я могу вызвать "AddAppUserBasic" в другом методе, который я вызываю, но он вызывает локальный метод. Не тот в запечатанном классе.

2 ответа

Вы НЕ ДОЛЖНЫ получать доступ к внутренним методам в классах. Внутренние методы являются внутренними по причине. Если вы считаете, что вам следует использовать внутренний метод - сначала поговорите с другим программистом, почему он сделал этот метод внутренним. Возможно по ошибке. Если нет, задайте вопрос, есть ли другой открытый метод, который вы должны использовать вместо этого.

Если вы действительно действительно хотите по какой-то причине использовать этот метод, И ВЫ ЗНАЕТЕ, ЧТО ВЫ ДЕЛАЕТЕ

Вы можете использовать отражение, чтобы сделать это:

using System.Reflection;

Type t = typeof(YourSealedClass); //get the type of your class
YourSealedClass obj = new YourSealedClass(); //somehow get the instance of the class

//find all non public methods
MethodInfo[] methods = t.GetMethods(BindingFlags.NonPublic|BindingFlags.Instance);

//next find your method. You can use LINQ or good old loop:
foreach(MethodInfo mi in methods)
  if(mi.Name == "MethodYouWantToUse")
  {
    mi.Invoke(obj, null);
    break; //leave the loop
  }

Вы можете прочитать больше об Invoke здесь: https://msdn.microsoft.com/pl-pl/library/a89hcwhh(v=vs.110).aspx

Просто - если вы вызываете Invoke, вам нужно передать объект класса и параметры метода - если таковые имеются.

Но помните - делая это, вы, вероятно, все испортите.

Вопреки распространенному мнению, существует способ доступа к внутренним методам класса. Проблема в том, что вы действительно не должны этого делать.

Это может не работать при определенных условиях, но концепция может быть доказана на этом примере. Давайте начнем с закрытого класса, который имеет внутренний метод:

namespace ClassLibrary1
{
    public sealed class SealedInternalExample
    {

        internal void TryAndExecuteMe (int someNumber)
        {
            System.Console.WriteLine("Internal method executed.  Parameter: {0}", 
                someNumber);
        }
    }
}

Вы не можете выполнить SealedInternalExample.TryAndExecuteMe через обычные соглашения о вызовах. Но вы можете сделать это с помощью отражения:

namespace CallInternalExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var classInstance = new SealedInternalExample();
            var methods = classInstance.GetType().GetMethods(
                System.Reflection.BindingFlags.NonPublic | 
                System.Reflection.BindingFlags.Public | 
                System.Reflection.BindingFlags.Instance);

            for (int x = 0; x < methods.Length; x++)
                System.Console.WriteLine("{0}: {1}", x, methods[x].Name);

            var internalMethod = methods.FirstOrDefault
                ((m) => m.Name.Equals("TryAndExecuteMe", 
                StringComparison.InvariantCulture));

            internalMethod.Invoke(classInstance, new object[] { 15 });

        }
    }
}

Выход программы:

0: TryAndExecuteMe
1: ToString
2: Equals
3: GetHashCode
4: GetType
5: Finalize
6: MemberwiseClone
Internal method executed.  Parameter: 15
Другие вопросы по тегам