C#如何判断对象是否实现了特定的方法
所以我有许多不同的潜在对象可以输出数据(字符串)。我想做的是运行一个通用的Output.WriteLine函数,其中包含一些潜在的参数,这些参数定义了输出到哪里。我的密码是-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
//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”方法
我遇到的两个问题是
编辑:我意识到向程序中添加公共属性是一个坏主意,如果您知道我可以如何避免它(需要能够从任何地方访问任何可写入线的表单对象,这是必要的),请尽一切努力详细说明。如果您的对象具有需要写入的数据,则其行为如下: 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);