简体   繁体   中英

Access internal method in a sealed class C#

I'm trying to access an Internal Method in a sealed class but since it is a sealed class, I'm not able to inherit the Internal Method. The backend portion of the solution I'm working on is designed like that.

I found a work around for this which uses an extension of the class

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);
    }

I tried this but no luck. I'm able to call "AddAppUserBasic" in another method that I'm calling but it is calling the local method. Not the one in the sealed class.

You MUST NOT access internal methods in classes. Internal methods are internal for a reason. If you think that you should use internal method - first talk to the other programmer why he/she made this method internal. Maybe by mistake. If not, aks if there is other public method that you should use instead.

If you really really really want for some reason to use that method, AND YOU KNOW WHAT YOU'RE DOING

You can use reflection to do that:

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
  }

You can read more about Invoke here: https://msdn.microsoft.com/pl-pl/library/a89hcwhh(v=vs.110).aspx

Simply - if you call Invoke you have to pass object of the class and parameters of the method - if any.

But remember - doing that you're probably going to mess things up.

Contrary to popular belief, there is a way to access internal methods on a class. The problem is that you really should not do this .

This may not work under certain conditions, but the concept can be proven using this example. Let's start with a sealed class that has an internal method:

namespace ClassLibrary1
{
    public sealed class SealedInternalExample
    {

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

You can't execute SealedInternalExample.TryAndExecuteMe via normal calling conventions. But you can do so via reflection:

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 });

        }
    }
}

The output of the program is:

0: TryAndExecuteMe
1: ToString
2: Equals
3: GetHashCode
4: GetType
5: Finalize
6: MemberwiseClone
Internal method executed.  Parameter: 15

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM