2009-09-11 8 views
6

特定のタイプに対して定義された演算子のリストを取得して、そのタイプに適用できる操作の種類を調べようとしています。例えば.netでタイプの定義された演算子を得る方法

、タイプのGuidは操作==!=をサポートしています。

したがって、例外が発生する前に、ユーザーが< =操作をGuidタイプに適用したい場合は、この状況を処理できます。

私は演算子のリストを持つことができた場合、ユーザーにリスト内の演算のみを使用させることができます。

演算子はオブジェクトブラウザに表示されるため、リフレクションによってアクセスする方法があるかもしれませんが、その方法は見つかりませんでした。

ご協力いただければ幸いです。

答えて

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); 
      } 
     } 
    } 
} 
+0

こんにちは、お返事ありがとうございました! 私はそれがほとんどの型のために働くと思いますが、Int32を試すと空のセットが返されます。 提案がありますか? – Cankut

+2

はい、プリミティブ型の演算子は、そのような "面白い"です。私はあなたが基本的にそれらのリストをハードコードしなければならないと思う。プリミティブに 'decimal'、' DateTime'、 'TimeSpan'や' Guid'が含まれていないことを忘れないでください。 –

+0

ありがとうございます:) – Cankut

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()); 
    } 
} 
} 
関連する問題