2017-05-05 46 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

你說得對。經過一些深層次的閱讀後,我必須稍微修改我的文章。 –