【问题标题】:Calling a private function from another class in C#从 C# 中的另一个类调用私有函数
【发布时间】:2018-10-09 23:21:40
【问题描述】:

我有一个名为Scenario2_Client.xaml.cs 的程序,它具有以下功能:

namespace SDKTemplate
{

    public sealed partial class Scenario2_Client : Page
    {
        private MainPage rootPage = MainPage.Current;
        // code

        // this is the function I would like to call
        private void RemoveValueChangedHandler() 
        {
            ValueChangedSubscribeToggle.Content = "Subscribe to value changes";
            if (subscribedForNotifications)
            {
                registeredCharacteristic.ValueChanged -= Characteristic_ValueChanged;
                registeredCharacteristic = null;
                subscribedForNotifications = false;
            }
        }
        // ...
    }
}

然后我在另一个名为EchoClient.cs 的文件(但在同一个项目中)中添加了一个类,该类具有以下代码:

namespace SDKTemplate
{
     class EchoClient
     {
         public void TcpClient()
         {
             try
             {
                 TcpClient client = new TcpClient("139.169.63.130", 9999);
                 StreamReader reader = new StreamReader(client.GetStream());
                 StreamWriter writer = new StreamWriter(client.GetStream());
                 string s = string.Empty;
                 while (!s.Equals("Exit"))
                 {
                     Console.WriteLine("TCP Client connected....");
                     Console.WriteLine("Enter a string or number to send to the server: ");
                     s = Console.ReadLine();                    
                     writer.WriteLine(s);
                     writer.Flush();
                     string server_string = reader.ReadLine();
                     Console.WriteLine(server_string);
                 }

                 reader.Dispose();
                 writer.Dispose();
                 client.Dispose();

             }
             catch (Exception e)
             {
                 Console.WriteLine(e);
             }
         }
     }


    internal class Console
    {
        internal static string ReadLine()
        {
            throw new NotImplementedException();
        }

        internal static void WriteLine(string v)
        {
            throw new NotImplementedException();
        }

        internal static void WriteLine(Exception e)
        {
            throw new NotImplementedException();
        }


    internal class TcpClient
    {
        private string v1;
        private int v2;

        public TcpClient(string v1, int v2)
        {
            this.v1 = v1;
            this.v2 = v2;
        }

        internal void Dispose()
        {
            throw new NotImplementedException();
        }

        internal Stream GetStream()
        {
            throw new NotImplementedException();
        }
    }    
 }

有没有办法从这个类中调用该函数?

如果它是公开的,我会做这样的事情:

EchoClient client = new EchoClient()
client.somefunction();
client.somefunction();

..但是由于这个方法是private,我应该如何访问它?

【问题讨论】:

  • 如果你需要在外面访问它,为什么它首先是私有的?
  • 反射或更改访问修饰符。
  • @Broots Waymb 好吧,我没有把它设为私有。 Scenario2 是 Microsoft 在 git 上直接提供的示例。
  • 微软将该方法设为私有可能是有充分理由的。
  • 问陈规定型的留言板问题:您为什么要这样做?你想达到什么目的? 也就是说,可以使用反射调用私有方法。

标签: c#


【解决方案1】:

可以使用反射调用私有方法,如下所示。

var iMethod
  = client.GetType().GetMethod("somefunction",
                               BindingFlags.NonPublic | BindingFlags.Instance);
iMethod.Invoke(client, new object[]{});

【讨论】:

  • 所以这段代码会进入scenario2还是EchoClient?使用 System.Reflection; ?
【解决方案2】:

我不确定为什么@Codor 被否决,但这里的相同答案更加充实。首先我用私有方法创建一个类:

public class PrivateFunction
{
    private int _age;

    public PrivateFunction(int age)
    {
        _age = age;
    }

    private int DoSomethingPrivate(string parameter)
    {
        Debug.WriteLine($"Parameter: {parameter}, Age: {_age}");
        return _age;
    }
}

我创建了一个方法,它接受参数并返回一个整数来显示所有可能性。

那我叫它:

   var type = typeof(PrivateFunction);
   var func = type.GetMethod("DoSomethingPrivate", BindingFlags.Instance | BindingFlags.NonPublic);
   var obj = new PrivateFunction(12);
   var ret = func.Invoke(obj, new[] {"some parameter"});
   Debug.WriteLine($"Function returned {ret}");

我在输出中得到了这个(证明发生了一些事情):

Parameter: some parameter, Age: 12
Function returned 12

如果您要重复调用相同的函数(可能使用不同的对象),请将MethodInfo 对象保存在func 中。它是不可变且可重复使用的。

【讨论】:

  • 嗯...有人不喜欢使用反射来调用私有方法。为什么对这个答案和@Codor 投反对票。这直接回答了“从 C# 中的另一个类调用私有函数”的问题。据我所知,这是回答它的唯一方法。也许有人对这样做有哲学上的反对?
  • 看到了这个视频:[youtube.com/watch?v=JztHEM7Wm3c]他正在使用反射访问类外的私有方法并被否决。
  • 一般不建议这样做。您正在打破最初开发人员的假设,因此您正在进入未经测试的水域。但是,有时您需要这样做。使用反射(类似于@Codor 和我发布的内容)是这样做的方法。
  • 感谢您的回答。但是我如何按照这个在我的问题中使用它?例如,假设场景 2 是我的私有函数,然后我去 EchoClient 类并调用你提到的方法?
  • 我的PrivateFunction 课程对应于您的Scenario2_Client 课程。我的 DoSomethingPrivate 方法对应于您的 RemoveValueChangedHandler 方法(即您要调用的私有方法)。无论你想调用它,获取Scenario2_Client的类型,然后获取MethodInfo对应的RemoveValueChangedHandler(使用GetMethod)和Invoke它。
猜你喜欢
  • 2020-10-13
  • 2015-07-04
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多