如何在.net中获取类型的定义运算符
Posted
技术标签:
【中文标题】如何在.net中获取类型的定义运算符【英文标题】:How to get defined operators for a type in .net 【发布时间】:2022-01-20 17:33:16 【问题描述】:我正在尝试获取特定类型的已定义运算符列表,以查看可以将哪种操作应用于该类型。
例如,Guid 类型支持 == 和 != 操作。
因此,如果用户想要对 Guid 类型应用 操作,我可以在异常发生之前处理这种情况。
或者,如果我有运算符列表,我可以强制用户只使用列表中的操作。
在对象浏览器中可以看到运算符,因此可能有一种方法可以通过反射访问它们,但我找不到那种方法。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:使用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(BindingFlags.Static | BindingFlags.Public))
if (method.IsSpecialName && method.Name.StartsWith("op_"))
Console.WriteLine(method.Name);
【讨论】:
嗨,感谢您的快速回复!我认为这适用于大多数类型,但是当我尝试 Int32 时,它返回一个空集。有什么建议吗? 是的,原始类型的运算符就是这样“有趣”的。我怀疑您基本上必须对它们的列表进行硬编码。不要忘记原语不包括decimal
、DateTime
、TimeSpan or
Guid`。
为了完整起见,Nullable<T>
上的“提升”运算符也可以称为“有趣”;-p
你不想过滤if (method.IsSpecialName) && method.Name.StartsWith("op_"))
否则你也会得到属性getter和setter
@Charlieface:你当然可以,是的。不知道是不是特别需要……【参考方案2】:
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());
【讨论】:
以上是关于如何在.net中获取类型的定义运算符的主要内容,如果未能解决你的问题,请参考以下文章
.NET Core/EF Core 2.0 升级后急切加载“类型之间未定义强制运算符”
Flutter:没有为“Object”类型定义运算符“[]”。尝试定义运算符'[]'
如何修复 SQLSTATE [42704]:未定义对象:7 错误:数据类型 json 在heroku 托管中没有访问方法“btree”的默认运算符类