Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get defined operators for a type in .net

I'm trying to get the list of defined operators for a specific type in order to see what kind of operations can be applied to that type.

For example, the type Guid supports operations == and !=.

So if user wants to apply <= operation for a Guid type I can handle this situation before an exception occurs.

Or if I could have the list of operators, I can force user to use only operations in the list.

The operators are seen in the object browser so there may be a way to access them via reflection but I couldn't find that way.

Any help will be appreciated.

like image 217
Cankut Avatar asked Sep 11 '09 19:09

Cankut


People also ask

How do you check what type an object is C#?

To determine whether an object is a specific type, you can use your language's type comparison keyword or construct. For example, you can use the TypeOf… Is construct in Visual Basic or the is keyword in C#. The GetType method is inherited by all types that derive from Object.

Which of the following operator returns a type object for the specified type?

The GetType operator returns the Type object for the specified typename .

What is the difference between += and =+ in C#?

+ is an arithmetic operator while += is an assignment operator..

Which keyword or operator is used to check if an object belongs to a particular type?

The is operator is used to check if the run-time type of an object is compatible with the given type or not. It returns true if the given object is of the same type otherwise, return false. It also returns false for null objects. Here, the expression will be evaluated to an instance of some type.


2 Answers

Get the methods with Type.GetMethods, then use MethodInfo.IsSpecialName to discover operators, conversions etc. Here's an example:

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(BindingFlags.Static | BindingFlags.Public))
        {
            if (method.IsSpecialName && method.Name.StartsWith("op_"))
            {
                Console.WriteLine(method.Name);
            }
        }
    }
}
like image 124
Jon Skeet Avatar answered Sep 28 '22 11:09

Jon Skeet


C# 4.0 has dynamic language runtime feature, so how about using the dynamic type?

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());
    }
}
}
like image 38
chris Avatar answered Sep 28 '22 12:09

chris