2017-05-05 58 views
-2

我试图访问一个密封类中的内部方法,但由于它是一个密封类,我无法继承内部方法。我正在开发的解决方案的后端部分就是这样设计的。在密封类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”,但它调用本地方法。不是密封课程中的人员。

+0

看看Access-Modifier'internal',也许你错过了关于该修饰符的一些东西。 [这里](https://msdn.microsoft.com/en-us/library/7c5ka91b.aspx) –

+1

问设计师他们为什么决定做这个内部。你应该将自己与团队的其他成员同步 –

+0

你不能从密封的课程中单独继承任何内部方法。 –

回答

0

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

这可能无法在某些条件下正常工作,但可以使用此示例验证此概念。让我们开始有一个内部方法,密封类:

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

你可以阅读更多关于调用这里:https://msdn.microsoft.com/pl-pl/library/a89hcwhh(v=vs.110).aspx

简单 - 如果你调用调用你必须通过该方法的类和参数的对象 - 如果有的话。

但请记住 - 这样做你可能会搞砸了。

+0

你能解释一下为什么''你不能访问类中的内部方法''?当然,如果打算阻止使用(课外),那么你会使用私人而不是内部? – musefan

+0

你说得对。经过一些深层次的阅读后,我必须稍微修改我的文章。 –