如何在.net中获取类型的已定义运算符

时间:2009-09-11 19:08:30

标签: c# reflection operators

我正在尝试获取特定类型的已定义运算符列表,以便查看可以对该类型应用哪种操作。

例如, Guid 类型支持 == != 操作。

因此,如果用户想要为Guid类型应用< = 操作,我可以在异常发生之前处理这种情况。

或者,如果我可以拥有运算符列表,我可以强制用户仅使用列表中的操作。

在对象浏览器中可以看到运算符,因此可能有办法通过反射访问它们,但我找不到这种方式。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:10)

使用Type.GetMethods获取方法,然后使用MethodInfo.IsSpecialName来发现运算符,转换等。以下是一个示例:

using System;
using System.Reflection;

public class Foo
{
    public static Foo operator +(Foo x, Foo y)
    {
        return new Foo();
    }

    public static implicit operator string(Foo x)
    {
        return "";
    }
}

public class Example 
{

    public static void Main()
    {
        foreach (MethodInfo method in typeof(Foo).GetMethods())
        {
            if (method.IsSpecialName)
            {
                Console.WriteLine(method.Name);
            }
        }
    }
}

答案 1 :(得分:4)

C#4.0具有动态语言运行时功能,那么如何使用dynamic类型?

using Microsoft.CSharp.RuntimeBinder;

namespace ListOperatorsTest
{
class Program
{
    public static void ListOperators(object inst)
    {
        dynamic d = inst;

        try
        {
            var eq = d == d; // Yes, IntelliSense gives a warning here.
            // Despite this code looks weird, it will do
            // what it's supposed to do :-)
            Console.WriteLine("Type {0} supports ==", inst.GetType().Name);

        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            var eq = d <= d;
            Console.WriteLine("Type {0} supports <=", inst.GetType().Name);

        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            var eq = d < d;
            Console.WriteLine("Type {0} supports <", inst.GetType().Name);

        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            var add = d + d;
            Console.WriteLine("Type {0} supports +", inst.GetType().Name);
        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            var sub = d - d;
            Console.WriteLine("Type {0} supports -", inst.GetType().Name);
        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            var mul = d * d;
            Console.WriteLine("Type {0} supports *", inst.GetType().Name);
        }
        catch (RuntimeBinderException)
        {
        }

        try
        {
            try
            {
                var div = d / d;
            }
            catch (DivideByZeroException)
            {
            }
            Console.WriteLine("Type {0} supports /", inst.GetType().Name);
        }
        catch (RuntimeBinderException)
        {
        }
    }

    private struct DummyStruct
    {
    }

    static void Main(string[] args)
    {
        ListOperators(0);
        ListOperators(0.0);
        DummyStruct ds;
        ListOperators(ds);
        ListOperators(new Guid());
    }
}
}