【问题标题】:Reflection and Operator Overloads in C#C# 中的反射和运算符重载
【发布时间】:2011-03-02 06:43:16
【问题描述】:

这是交易。我有一个程序,它将加载给定的程序集,解析所有类型及其成员并编译 TreeView(非常类似于旧的 MSDN 站点),然后为 TreeView 中的每个节点构建 HTML 页面。它基本上需要一个给定的程序集,并允许用户为它创建自己的类似 MSDN 的库以用于文档目的。

这是我遇到的问题:每当在定义的类中遇到运算符重载时,反射将其作为“MethodInfo”返回,其名称设置为“op_Assign”或“op_Equality”之类的名称。我希望能够捕获这些并正确列出它们,但我在返回的 MethodInfo 对象中找不到任何内容,以准确识别我正在查看操作员。

我绝对不想只捕获以“op_”开头的所有内容,因为这肯定会(在某些时候)会采用不应该采用的方法。我知道像这样的“特殊情况”的其他方法和属性设置了“IsSpecialName”属性,但显然运算符并非如此。

我已经在网上搜索并绞尽脑汁花了两天时间试图弄清楚这一点,所以任何帮助都将不胜感激。

【问题讨论】:

标签: c# reflection operator-overloading


【解决方案1】:

op_ 命名约定是 .net 的标准或事实上的标准。反思时,我会这样做:

public void GenerateDocForMethod(MethodInfo method)
{
    if(method.Name.StartsWith("op_"))
        GenerateDocForOperator(method);
    else
        GenerateDocForStandardMethod(method);
}

public void GenerateDocForOperator(MethodInfo method)
{
    switch(method.Name)
    {
        case "op_Addition":
        //generate and handle other cases...

        //handle methods that just happen to start with op_
        default:
            GenerateDocForStandardMethod(method);
    }
}

public void GenerateDocForStandardMethod(MethodInfo method)
{
    //generate doc
}

GenerateDocForOperator 将打开所有可重载的运算符(不要忘记隐式和显式转换)。如果方法名称不是标准运算符名称之一,则调用 GenerateDocForStandardMethod。我找不到详尽的运算符方法名称列表,但如果您真的需要,我可能会提供一个完整的列表。

编辑: 以下是可重载运算符的方法名称列表(取自http://forums.devx.com/showthread.php?55322-Operator-Overloading.....C-can-do-it....&p=208952#post208952):

op_Implicit
op_Explicit
op_Addition
op_减法
op_Multiply
op_Division
op_Modulus
op_ExclusiveOr
op_BitwiseAnd
op_BitwiseOr
op_LogicalAnd
op_LogicalOr
op_Assign
op_LeftShift
op_RightShift
op_SignedRightShift
op_UnsignedRightShift
op_Equality
op_GreaterThan
op_LessThan
op_不等式
op_GreaterThanOrEqual
op_LessThanOrEqual
op_MultiplicationAssignment
op_SubtractionAssignment
op_ExclusiveOrAssignment
op_LeftShiftAssignment
op_ModulusAssignment
op_AdditionAssignment
op_BitwiseAndAssignment
op_BitwiseOrAssignment
op_逗号
op_DivisionAssignment
op_递减
op_Increment
op_UnaryNegation
op_UnaryPlus
op_OnesComplement

【讨论】:

  • 实际上,这是一个很好的处理方法。谢谢。猜猜我太着迷于找到一个定义值来识别操作员。顺便说一句,我想知道如果我用加法运算符重载创建一个名为“op_Addition”的随机方法的类会发生什么。我想知道编译器是否会让你这样做?对我来说,这听起来像是接下来几分钟的实验:) 再次感谢。碰巧知道我在哪里可以获得所有可能的 op_XXXX 值的列表?
  • 我也很难找到列表。你摇滚:)
  • Mike U: 只是因为我对结果很好奇:如果你定义一个类似操作符的方法,它不会编译:类型 'Foo' 已经定义了一个具有相同参数的名为 'op_Addition' 的成员类型
  • 注意:所有这些都可能用于一些 .NET 框架语言,但C# 编译器利用有符号移位运算符或赋值运算符。或逗号运算符。
【解决方案2】:

运算符重载确实会将 IsSpecialName 标志设置为 true。 如果你通过显式地给它们一个像 op_* 这样的名字来实现这些方法,那么这个标志就会被设置为 false。

【讨论】:

    【解决方案3】:

    添加到 Wiser 的帖子中:同一线程 (http://forums.devx.com/showthread.php?55322-Operator-Overloading.....C-can-do-it....&p=208952#post208952) 提到了一些额外的操作符:

    Some additions - see CLI Partition 1, section 10.3.
     op_UnsignedRightShiftAssignment
     op_RightShiftAssignment
     op_MemberSelection
     op_PointerToMemberSelection
     op_LogicalNot
     op_True
     op_False
     op_AddressOf
     op_PointerDereference
    

    这些运算符可在 The Common Language Infrastructure Annotated Standard 一书中看到:http://books.google.ru/books?id=50PhgS8vjhwC&pg=PA111&lpg=PA111&dq=op_PointerToMemberSelection&source=bl&ots=vZIC0nA9sW&sig=4hTfAAWGkaKirgBQ4I1yBnK_D2M&hl=en&sa=X&ei=YsB2ULvAMuHx4QT25YCYAw&ved=0CB0Q6AEwAA#v=onepage&q=op_PointerToMemberSelection&f=false

    也可以在这里找到一些方便的表格:http://en.csharp-online.net/Common_Type_System%E2%80%94Operator_Overloading

    【讨论】:

    • 注意:所有这些都可能用于一些 .NET 框架语言,但在此列表中,C# 编译器利用了 LogicalNot 、True 和 False 运算符。并且它更喜欢 implicit operator bool 而不是 True 和 False 运算符,如果两者都已定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2012-11-19
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    相关资源
    最近更新 更多