Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反思的使用/需要_C#_.net_Reflection - Fatal编程技术网

C# 反思的使用/需要

C# 反思的使用/需要,c#,.net,reflection,C#,.net,Reflection,我在这个论坛上搜索了这些问题,并找到了很好的资源。为了理解反射的概念,我自己编写了以下代码 static void Main(String[] args) { MyClass1 mc1 = new MyClass1(); Type t = mc1.GetType(); MethodInfo mInfo = t.GetMethod("method1"); object[] o=new object[]{2};

我在这个论坛上搜索了这些问题,并找到了很好的资源。为了理解反射的概念,我自己编写了以下代码

static void Main(String[] args)
    {

        MyClass1 mc1 = new MyClass1();
        Type t = mc1.GetType();
        MethodInfo mInfo = t.GetMethod("method1");
        object[] o=new object[]{2};
        Console.WriteLine(mInfo.Invoke(mc1, o));
        NameSpace2.Class1 c1 = new NameSpace2.Class1();
        Type t2 = c1.GetType();
        MethodInfo[] mI2 = t2.GetMethods();
        object[] o2 = new object[] {2,3};
        foreach (MethodInfo m in mI2)
        {
            Console.WriteLine(m);
        }

        object x = Activator.CreateInstance(t);

        Console.WriteLine(x.GetType());
        Console.Read();

    }

我知道,通过反射,我将能够在运行时获得有关类型、公共方法、对象属性的信息,并且还能够创建该类型的对象。但我的观点是,除非我知道这些方法需要哪些参数作为输入,否则我将无法实现任何方法,而这些信息只能在运行时提供。那么,反射的重要性是什么,它仅仅是关于一个物体的信息吗?

谈谈你的隐含问题

但我的观点是,除非我知道这些方法需要哪些参数作为输入,否则我将无法实现任何方法,而这些信息只能在运行时提供

我们举个简单的例子怎么样。我想在一个需要参数的类上实例化一个方法,我将成为引导者,也就是说,我将创建该类并启动该方法,但我对此一无所知

public class Foo
{
    public Foo() { }

    public void FooMethod(string parm) { }
}

public class Facilitator
{
    public void RaiseAction(string type, string action, params object[] parm)
    {
        var o = Activator.CreateInstance("MyAssembly", type);
        var methodInfo = o.GetType().GetMethod(action);
        if (methodInfo == null) { return; }
        methodInfo.Invoke(o, parm);
    }
}
现在,在上面的例子中,我只是在一个我一无所知的对象上向一个方法传递了参数

现在,让我们来看看其他一些可以通过反射实现的事情。让我们想象一下,我需要找一个私人成员——尽管这通常是一个坏主意——如果必要的话,我可以这样做,有时我也会这样做以进行调试和黑客攻击。您是否曾经想要一个在运行时无法访问的标志来帮助您做出决策?您在调试器中看到了该标志,但它隐藏在对象层次结构中,并且是私有的!更糟的是什么?微软表示,他们将在随后的版本中以某种方式将其公开,但你需要马上离开,你需要这个标志!或者你需要这个方法

考虑一下这个例子,其中o是某个对象,您需要从中获得一些私有的东西:

var propertyInfo = o.GetType().GetProperty("SomePublicProperty");
if (propertyInfo == null) { return; }
var myFirstPrivateMember = propertyInfo.PropertyType.GetField("_somePrivateField", BindingFlags.Instance | BindingFlags.NonPublic);
哦,我们刚刚得到了第一个私人会员——还有一个领域

反射对我来说很重要,因为我构建了许多完全动态的应用程序,从数据库到用户体验。当您构建这样的应用程序时,您对任何事情都不太了解—您没有配置它—但由于反射的灵活性,您可以调用并获得完成工作所需的任何东西


就像其他任何东西一样,这些都是反射的非常简单的例子,但希望你能很好地感受到反射的力量以及它为什么有用。在大多数日常应用程序中,您的世界是非常静态的,您可能永远不会使用它,但您需要扩展一点,使其更具动态性。

来回答您隐含的问题

但我的观点是,除非我知道这些方法需要哪些参数作为输入,否则我将无法实现任何方法,而这些信息只能在运行时提供

我们举个简单的例子怎么样。我想在一个需要参数的类上实例化一个方法,我将成为引导者,也就是说,我将创建该类并启动该方法,但我对此一无所知

public class Foo
{
    public Foo() { }

    public void FooMethod(string parm) { }
}

public class Facilitator
{
    public void RaiseAction(string type, string action, params object[] parm)
    {
        var o = Activator.CreateInstance("MyAssembly", type);
        var methodInfo = o.GetType().GetMethod(action);
        if (methodInfo == null) { return; }
        methodInfo.Invoke(o, parm);
    }
}
现在,在上面的例子中,我只是在一个我一无所知的对象上向一个方法传递了参数

现在,让我们来看看其他一些可以通过反射实现的事情。让我们想象一下,我需要找一个私人成员——尽管这通常是一个坏主意——如果必要的话,我可以这样做,有时我也会这样做以进行调试和黑客攻击。您是否曾经想要一个在运行时无法访问的标志来帮助您做出决策?您在调试器中看到了该标志,但它隐藏在对象层次结构中,并且是私有的!更糟的是什么?微软表示,他们将在随后的版本中以某种方式将其公开,但你需要马上离开,你需要这个标志!或者你需要这个方法

考虑一下这个例子,其中o是某个对象,您需要从中获得一些私有的东西:

var propertyInfo = o.GetType().GetProperty("SomePublicProperty");
if (propertyInfo == null) { return; }
var myFirstPrivateMember = propertyInfo.PropertyType.GetField("_somePrivateField", BindingFlags.Instance | BindingFlags.NonPublic);
哦,我们刚刚得到了第一个私人会员——还有一个领域

反射对我来说很重要,因为我构建了许多完全动态的应用程序,从数据库到用户体验。当您构建这样的应用程序时,您对任何事情都不太了解—您没有配置它—但由于反射的灵活性,您可以调用并获得完成工作所需的任何东西


就像其他任何东西一样,这些都是反射的非常简单的例子,但希望你能很好地感受到反射的力量以及它为什么有用。在大多数日常应用程序中,您的世界是非常静态的,您可能永远不会使用它,但您需要扩展一点并获得更大的动态性。

如果您需要反射,那么您的需求无法在编译时解决,而只能在运行时解决

假设您正在制作一个需要模块化的酷应用程序,您可以让开发人员为您的应用程序编写插件 应用 你不能为可能创建的每个插件编译应用程序。然后,您需要加载、内省并使用反射调用插件的对象

static void Main(String[] args)
    {

        MyClass1 mc1 = new MyClass1();
        Type t = mc1.GetType();
        MethodInfo mInfo = t.GetMethod("method1");
        object[] o=new object[]{2};
        Console.WriteLine(mInfo.Invoke(mc1, o));
        NameSpace2.Class1 c1 = new NameSpace2.Class1();
        Type t2 = c1.GetType();
        MethodInfo[] mI2 = t2.GetMethods();
        object[] o2 = new object[] {2,3};
        foreach (MethodInfo m in mI2)
        {
            Console.WriteLine(m);
        }

        object x = Activator.CreateInstance(t);

        Console.WriteLine(x.GetType());
        Console.Read();

    }
假设您正在为银行应用程序制作一个中间件,该中间件负责处理数据库连接并使用该数据执行一些业务逻辑。您可以为每个可用的数据库编码和编译中间件。或者您可以编写一次代码,只需在运行时激活并使用正确的数据库驱动程序

如果您希望动态获取web服务的WSDL,生成代理,并在代理被编译并加载到内存后立即使用web服务,该怎么办?想不出在编译时执行此操作的方法

更好的是,如果您使用CodeDOM生成代码,编译、加载已编译的程序集并使用刚刚编译的对象,该怎么办


总有一天你会需要使用反射。我希望如此…

如果您需要反射,那么您的需求不能在编译时解决,而是在运行时解决

假设您正在制作一个需要模块化的很酷的应用程序,您可以让开发人员为您的应用程序编写插件。 你不能为可能创建的每个插件编译应用程序。然后,您需要加载、内省并使用反射调用插件的对象

static void Main(String[] args)
    {

        MyClass1 mc1 = new MyClass1();
        Type t = mc1.GetType();
        MethodInfo mInfo = t.GetMethod("method1");
        object[] o=new object[]{2};
        Console.WriteLine(mInfo.Invoke(mc1, o));
        NameSpace2.Class1 c1 = new NameSpace2.Class1();
        Type t2 = c1.GetType();
        MethodInfo[] mI2 = t2.GetMethods();
        object[] o2 = new object[] {2,3};
        foreach (MethodInfo m in mI2)
        {
            Console.WriteLine(m);
        }

        object x = Activator.CreateInstance(t);

        Console.WriteLine(x.GetType());
        Console.Read();

    }
假设您正在为银行应用程序制作一个中间件,该中间件负责处理数据库连接并使用该数据执行一些业务逻辑。您可以为每个可用的数据库编码和编译中间件。或者您可以编写一次代码,只需在运行时激活并使用正确的数据库驱动程序

如果您希望动态获取web服务的WSDL,生成代理,并在代理被编译并加载到内存后立即使用web服务,该怎么办?想不出在编译时执行此操作的方法

更好的是,如果您使用CodeDOM生成代码,编译、加载已编译的程序集并使用刚刚编译的对象,该怎么办


总有一天你会需要使用反射。我希望如此……

除了Adrian Salazar的回答之外,我还有一些我在过去几年中遇到的例子:

自动包装器生成。我编写了一个使用OpenGL/OpenAL的跨平台框架,为了保持简单,我使用了在设备可用后初始化的委托。在iOS上,我需要将每个方法声明为带有dll导入属性的extern方法。OpenGL/OpenAL都有很多方法,所以我只是编译了委托,编写了一个程序,为我编写了一个*.cs文件,声明了所有这些方法。现在,这让我安全了一个星期的痛苦工作,保持这个包装最新。 代理生成。我曾经编写过一个应用程序,它必须能够处理flash对象,并在PropertySpector中显示它们的属性,并调用对象的方法。为了能够做到这一点,我编写了一个IL生成器,并使用反射来反射属性并调用方法。 最常见的示例应该是:加载和保存数据。这项任务主要是通过使用反射来完成的。我在2012中编写了一个XML读写器,它允许初始化像XAML中的对象一样的对象,并将这些对象再次保存到XML中。如果不使用反射,则对象初始化和将它们重新写入XML是一项需要大量工作的任务。
正如你所看到的,有很多例子证明反射是非常有用的。在过去的8年中,我多次使用反射,我甚至无法计算使用的次数

除了Adrian Salazar的回答之外,我还有一些我在过去几年中遇到的例子:

自动包装器生成。我编写了一个使用OpenGL/OpenAL的跨平台框架,为了保持简单,我使用了在设备可用后初始化的委托。在iOS上,我需要将每个方法声明为带有dll导入属性的extern方法。OpenGL/OpenAL都有很多方法,所以我只是编译了委托,编写了一个程序,为我编写了一个*.cs文件,声明了所有这些方法。现在,这让我安全了一个星期的痛苦工作,保持这个包装最新。 代理生成。我曾经编写过一个应用程序,它必须能够处理flash对象,并在PropertySpector中显示它们的属性,并调用对象的方法。为了能够做到这一点,我编写了一个IL生成器,并使用反射来反射属性并调用方法。 最常见的示例应该是:加载和保存数据。这项任务主要是通过使用反射来完成的。我在2012中编写了一个XML读写器,它允许初始化像XAML中的对象一样的对象,并将这些对象再次保存到XML中。如果不使用反射,则对象初始化和将它们重新写入XML是一项需要大量工作的任务。 正如你所看到的,有很多例子证明反射是非常有用的。
在过去的8年中,我多次使用反射,我甚至无法计算使用的次数

例如,您可以从文件中读取字符串method1?ORM和数据绑定是反射之美的很好的例子。可能的重复您是否想过VisualStudio的属性窗口是如何实现的??我不认为会有猴子为他们添加的每个对象键入编辑器窗口-我的意思不是不尊重,只是一个说明性的笑话:例如,你可以从文件中读取字符串method1?ORM和数据绑定是反射之美的很好的例子。可能重复。你有没有想过VisualStudio的属性窗口是如何实现的??我不认为会有猴子为他们添加的每个对象键入编辑器窗口-我的意思不是不尊重,只是一个说明性的笑话: