Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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#_Class_Object_Methods_Console - Fatal编程技术网

C#如何判断对象是否实现了特定的方法

C#如何判断对象是否实现了特定的方法,c#,class,object,methods,console,C#,Class,Object,Methods,Console,所以我有许多不同的潜在对象可以输出数据(字符串)。我想做的是运行一个通用的Output.WriteLine函数,其中包含一些潜在的参数,这些参数定义了输出到哪里。我的密码是- //Defined in static class Const public enum Out : int { Debug = 0x01, Main = 0x02, Code = 0x04 }; static class Output { private static List<object> Ret

所以我有许多不同的潜在对象可以输出数据(字符串)。我想做的是运行一个通用的Output.WriteLine函数,其中包含一些潜在的参数,这些参数定义了输出到哪里。我的密码是-

//Defined in static class Const
public enum Out : int { Debug = 0x01, Main = 0x02, Code = 0x04 };

static class Output
{
    private static List<object> RetrieveOutputMechanisms(Const.Out output)
    {
        List<object> result = new List<object>();

    #if DEBUG
        if (bitmask(output, Const.Out.Debug))
            result.Add(1);//Console); //I want to add Console here, but its static
    #endif
        if (bitmask(output, Const.Out.Main))
            if (Program.mainForm != null)
                result.Add(Program.mainForm.Box);

        if (bitmask(output, Const.Out.Code))
            if (Program.code!= null)
                result.Add(Program.code.Box);

        return result;
    }

    public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
    {
        Console.WriteLine(
        List<object> writers = RetrieveOutputMechanisms(output);
        foreach (object writer in writers)
            writer.WriteLine(str, color);
    }
}
//在静态类Const中定义
公共枚举输出:int{Debug=0x01,Main=0x02,Code=0x04};
静态类输出
{
私有静态列表检索输出机制(Const.Out输出)
{
列表结果=新列表();
#如果调试
if(位掩码(输出、常量输出、调试))
result.Add(1);//控制台);//我想在这里添加控制台,但它是静态的
#恩迪夫
if(位掩码(输出,常量输出主))
if(Program.mainForm!=null)
结果.添加(Program.mainForm.Box);
if(位掩码(输出,常量输出代码))
if(程序代码!=null)
结果.添加(程序.代码.框);
返回结果;
}
公共静态void WriteLine(颜色、字符串str、常量输出=Const.Out.Debug和Const.Out.Main)
{
控制台写入线(
列表编写器=检索输出机制(输出);
foreach(写入程序中的对象写入程序)
writer.WriteLine(str,color);
}
}
问题的关键是,输出目的地并不总是存在的,因为它们在调用这些调用时可能存在,也可能不存在。因此,我们的想法是确定您要打印到的对象,确定它是否存在,将它添加到要打印到的对象列表中,然后循环并打印到所有这些对象(如果它们已实现)使用“WriteLine”方法

我遇到的两个问题是

  • 该控制台是一个静态类,不能正确地(据我所知)添加到对象列表中
  • 我不知道如何断言列表中的对象定义WriteLine,并将它们强制转换为可以应用于多个基类型的对象。假设我可以让Console在这个方案中正常工作,这将是一个明显的问题,它与实际的框不是同一个基类型,而且,如果我有一个不是框的对象,那么,做这样的事情就太好了

    foreach(写入程序中的对象写入程序) .WriteLine(str,彩色)

  • 这样我就不用单独投了

    我不只是从RetrieveOutputMechanisms函数中写入Line的更大原因是,我希望这不仅仅包括WriteLine,这意味着我需要将位掩码代码复制到每个函数


    编辑:我意识到向程序中添加公共属性是一个坏主意,如果您知道我可以如何避免它(需要能够从任何地方访问任何可写入线的表单对象,这是必要的),请尽一切努力详细说明。

    如果您的对象具有需要写入的数据,则其行为如下:

    A始终写入控制台和日志 B总是写日志 C总是写入控制台

    对于所有数据,最好是声明一个接口,并让每个接口实现用于输出的接口方法。然后,在调用代码中,不要将它们声明为实际类型,而是将它们声明为类型IOOUTPUT或具有该方法的任何接口。然后有两个助手方法,一个用于实际输出到控制台and一个用于实际输出到日志文件。a将调用两个助手,B和C分别调用它们各自的助手

    另一方面,如果对象将在不同的时间写入不同的日志:

    A、 B和C有时写入控制台,有时写入日志,具体取决于某些属性

    然后,我建议您创建一个事件处理程序,以便在类需要写入某些内容时使用。然后,使用逻辑来识别哪些内容写入控制台,哪些内容写入侦听器类,并将适当的内容附加到该输出事件。这样,您就可以在封装的类中保留关于写入内容的逻辑只需使用这种功能,同时让A、B和C类不依赖于可能会影响你的路径。考虑使用一个位掩码来描述一个完整的方法。一旦A、B或C的日志记录行为发生变化,或者如果需要添加新的输出,则突然需要担心一个类或方法。一次影响所有的程序。这使得它的可维护性降低,并且测试bug也更加困难

    MethodInfo methodname = typeof(object).GetMethod("MethodA");
    

    然后使用if语句检查methodname是否为null。

    一种方法是使用
    操作(委托)并将其存储在
    列表中。这将适用于
    控制台
    和任何其他类,因为您可以轻松编写lambda(或2.0委托)将输出变量映射到被调用方法中的正确参数。无需强制转换。其工作原理如下:

    (假设您使用的是C#3.5或更高版本,但您可以在2.0或使用委托的任何版本中完成所有这些操作)

    然后,在程序的其他地方,如form类中,要注册编写器,请执行以下操作:

    Output.Instance.Register(Const.Out.Main, (s, c) => this.Box.WriteLine(s, c));
    
    卸载表单后,您可以执行以下操作:

    Output.Instance.Unregister(Const.Out.Main);
    

    然后,另一种方法是不使用单例。然后,您可以有多个用于不同目的的
    输出
    实例,然后将这些实例注入到其他类中。例如,更改主窗体的构造函数以接受
    输出
    参数,并将其存储为对象变量以供以后使用。主窗体用于然后m可以将其传递给同样需要它的子窗体。

    我的方法的主要缺点是,我需要向程序中添加公共变量才能完成此操作,尽管在这之后,添加新的输出不会改变任何其他内容。编写侦听器类对我没有帮助,因为我的大部分问题都与确定某个内容是否实现有关这仍然是一个问题,我不是
    Output.Instance.Register(Const.Out.Main, (s, c) => this.Box.WriteLine(s, c));
    
    Output.Instance.Unregister(Const.Out.Main);