【问题标题】:Access internal method in a sealed class C#访问密封类 C# 中的内部方法
【发布时间】:2017-10-03 19:23:57
【问题描述】:

我正在尝试访问密封类中的内部方法,但由于它是密封类,我无法继承内部方法。我正在研究的解决方案的后端部分就是这样设计的。

我找到了一个使用类扩展的解决方法

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”,但它正在调用本地方法。不是密封类中的那个。

【问题讨论】:

  • 看看 Access-Modifier internal,也许你缺少关于该修饰符的一些东西。 Here
  • 询问设计师为什么他们决定将其内部化。您应该将自己与团队其他成员同步
  • 你不能从密封类继承任何东西,不管内部方法。
  • 您没有指定为什么不能调用内部方法。 sealedinternal 没有直接关系。你的类是密封的,但这确实意味着你可以创建它的一个实例。您的方法是内部的,因此您应该能够从定义它的程序集中调用它。那个大会在你的控制之下吗?你不说如果是这样。
  • 另外,你的扩展方法只是在调用自己。

标签: c# class methods internal sealed


【解决方案1】:

您不得访问类中的内部方法。内部方法是内部的,这是有原因的。如果您认为应该使用内部方法 - 首先与其他程序员讨论他/她为什么使用内部方法。也许是误会。如果没有,请询​​问您是否应该使用其他公共方法。

如果你真的真的很想使用这种方法,你知道你在做什么

您可以使用反射来做到这一点:

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,你必须传递类的对象和方法的参数——如果有的话。

但请记住 - 这样做你可能会把事情搞砸。

【讨论】:

  • 你能解释一下为什么"you must not access internal methods in classes"吗?当然,如果目的是阻止使用(在课堂之外),那么您会使用私有而不是内部?
  • 你是对的。经过深入阅读后,我必须稍微修改一下我的帖子。
  • 调用内部方法是完全合法的。是的,如果你不知道自己在做什么,那就不要灰心了。但是如果 - 例如 - 你有源代码,并且你在一个版本锁定的库中,并且需要这些方法......那么实际上没有理由避免它。我希望人们不要再讨厌它了。内部代码不断被开发人员错误地使用和滥用,因此有很多代码不需要是内部的,也不应该是内部的。反射通常是修复代码的唯一方法。
  • 但是你必须知道这不是反思的原因。已为其他问题创建了反思。但是,是的,有时这是唯一的方法。
  • 在密封类中“设置”只读访问器就像一个魅力。
【解决方案2】:

与流行的看法相反,有一种方法可以访问类的内部方法。问题是你真的不应该这样做

这在某些条件下可能不起作用,但可以使用此示例证明该概念。让我们从一个有内部方法的密封类开始:

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

【讨论】:

    猜你喜欢
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多