简体   繁体   English

在密封的C#类中访问内部方法

[英]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. 我可以在另一个正在调用的方法中调用“ AddAppUserBasic”,但它正在调用本地方法。 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 您可以在此处阅读有关Invoke的更多信息: 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. 简单-如果调用Invoke,则必须传递方法的类和参数的对象-如果有的话。

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. 您无法通过常规调用约定执行SealedInternalExample.TryAndExecuteMe 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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