【问题标题】:Extending the "<" and ">" operator for System.Type [duplicate]扩展 System.Type 的“<”和“>”运算符 [重复]
【发布时间】:2012-03-28 21:02:21
【问题描述】:

可能重复:
Operator Overloading with C# Extension Methods

如何重载那些操作符,感觉被编译器误解了。

我认为核心问题是我试图将运算符重载为类的扩展。类型类没有这些运算符,所以我觉得这样做很安全 - 但我的编译器不同意。

    public static class TypeCheck
    {
        public static Boolean ToBool(this Type t1, Type t2)
        {
            //normal extension works
            return true;
        }

        public static Boolean operator > (this Type t1, Type t2)
        {
            //TODO once it compiles
            return fasle;
        }

        public static Boolean operator < (this Type t1, Type t2)
        {
            //TODO once it compiles
            return true;
        }

    }

澄清这些比较的领域细节:class A : B {}class B {}class C {} A 大于 A 且大于 B,但小于其余部分。因为 A.IsCastableTo(B) 和 A.IsCastableTo(A);

【问题讨论】:

  • 你在这里找到答案stackoverflow.com/questions/172658/…
  • 我什至不明白一种类型如何 > 或
  • @cadrell0:您可以将 class B : A 则为“B
  • 这不符合任何其他与 的比较如何工作。 17 不比 23 更具体。2012 年 1 月 1 日不比 2012 年 3 月 1 日更具体。 “ASDF”并不比“QWER”更具体。此外,当 C 定义为 class C { } 时,C &lt; B 会返回什么。如果你告诉我应该返回 false,那么我希望 C &gt; BC == B 返回 true。
  • 我是 cadrell0,这里的用例是什么?有什么味道……

标签: c# operator-overloading


【解决方案1】:

C# 中没有“扩展运算符”。

至少有一个运算符参数必须是声明运算符的类型。

【讨论】:

    【解决方案2】:

    正如其他人所说,C# 不支持扩展运算符。如果您需要这样做,那么您可以实现自定义类型,例如:

    public class MyType : Type
    {
        private Type internalType;
    
        public MyType(Type t)
        {
            internalType = t;
        }
    
        public static Boolean operator >(MyType t1, Type t2)
        {
            //TODO once it compiles
            return false;
        }
    
        public static Boolean operator <(MyType t1, Type t2)
        {
            //TODO once it compiles
            return true;
        }
    
        public override Assembly Assembly
        {
            get { return internalType.Assembly; }
        }
    
        public override string AssemblyQualifiedName
        {
            get { return internalType.AssemblyQualifiedName; }
        }
    
        public override Type BaseType
        {
            get { return internalType.BaseType; }
        }
    
        public override string FullName
        {
            get { return internalType.FullName; }
        }
    
        public override Guid GUID
        {
            get { return internalType.GUID; }
        }
    
        protected override TypeAttributes GetAttributeFlagsImpl()
        {
            return internalType.Attributes;
        }
    
        protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
        {
            return internalType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers);
        }
    
        public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
        {
            return internalType.GetConstructors(bindingAttr);
        }
    
        public override Type GetElementType()
        {
            return GetElementType();
        }
    
        public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
        {
            return internalType.GetEvent(name, bindingAttr);
        }
    
        public override EventInfo[] GetEvents(BindingFlags bindingAttr)
        {
            return internalType.GetEvents(bindingAttr);
        }
    
        public override FieldInfo GetField(string name, BindingFlags bindingAttr)
        {
            return internalType.GetField(name, bindingAttr);
        }
    
        public override FieldInfo[] GetFields(BindingFlags bindingAttr)
        {
            return internalType.GetFields(bindingAttr);
        }
    
        public override Type GetInterface(string name, bool ignoreCase)
        {
            return internalType.GetInterface(name, ignoreCase);
        }
    
        public override Type[] GetInterfaces()
        {
            return internalType.GetInterfaces();
        }
    
        public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
        {
            return internalType.GetMembers(bindingAttr);
        }
    
        protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
        {
            return internalType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
        }
    
        public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
        {
            return internalType.GetMethods(bindingAttr);
        }
    
        public override Type GetNestedType(string name, BindingFlags bindingAttr)
        {
            return internalType.GetNestedType(name, bindingAttr);
        }
    
        public override Type[] GetNestedTypes(BindingFlags bindingAttr)
        {
            return internalType.GetNestedTypes(bindingAttr);
        }
    
        public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
        {
            return internalType.GetProperties(bindingAttr);
        }
    
        protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
        {
            return internalType.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
        }
    
        protected override bool HasElementTypeImpl()
        {
            return internalType.HasElementType;
        }
    
        public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
        {
            return internalType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
        }
    
        protected override bool IsArrayImpl()
        {
            return internalType.IsArray;
        }
    
        protected override bool IsByRefImpl()
        {
            return internalType.IsByRef;
        }
    
        protected override bool IsCOMObjectImpl()
        {
            return internalType.IsCOMObject;
        }
    
        protected override bool IsPointerImpl()
        {
            return internalType.IsPointer;
        }
    
        protected override bool IsPrimitiveImpl()
        {
            return internalType.IsPrimitive;
        }
    
        public override Module Module
        {
            get { return internalType.Module; }
        }
    
        public override string Namespace
        {
            get { return internalType.Namespace; }
        }
    
        public override Type UnderlyingSystemType
        {
            get { return internalType.UnderlyingSystemType; }
        }
    
        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
        {
            return internalType.GetCustomAttributes(attributeType, inherit);
        }
    
        public override object[] GetCustomAttributes(bool inherit)
        {
            return internalType.GetCustomAttributes(inherit);
        }
    
        public override bool IsDefined(Type attributeType, bool inherit)
        {
            return internalType.IsDefined(attributeType, inherit);
        }
    
        public override string Name
        {
            get { return internalType.Name; }
        }
    }
    

    另外,实现可以委托调用的自定义 DynamicObject (C# 4+) 可能会更容易。

    【讨论】:

      【解决方案3】:

      您可以在自己的类中重载运算符,但不能通过扩展方法方法在其他类中重载运算符。

      【讨论】:

        【解决方案4】:

        您不能将运算符行为定义为扩展方法。
        您可以像 DateTime 使用 Add()Subtract() 一样执行此操作,如果您无法修改类型实现,它们可以作为扩展方法实现。

        您也可以从类型继承(如果可能的话),并在那里定义运算符。

        【讨论】:

          猜你喜欢
          • 2020-04-13
          • 1970-01-01
          • 2021-01-17
          • 2017-12-20
          • 2021-05-21
          • 1970-01-01
          • 1970-01-01
          • 2021-03-16
          相关资源
          最近更新 更多