如何使用通用类的不同泛型类型的操作数来重载泛型类的操作符 [英] how to overload an operator of a generic class with operands of different generic types of the generic class

查看:127
本文介绍了如何使用通用类的不同泛型类型的操作数来重载泛型类的操作符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问了很多类似的问题,但都涉及相同类型或相同类型的操作数。这一个特别(我怎样才能使用泛型类型参数与运算符重载?)接近我所期望的,但没有答案或变通方法。



是否有可能为'*'操作符重载做这样的事情:

  public class MyNumericClass< T> 
{
public double Value {get;组; }

//确定,但只适用于相同类型的操作数
public static double operator *(MyNumericClass< T> left,MyNumericClass< T> right)
{
返回left.Value * right.Value;
}

// ****不同类型操作数的伪代码 - 不行****
公共静态双操作符*< TRight>(MyNumericClass< T>左,MyNumericClass< TRight>右)
{
return left.Value * right.Value;
}

static void Test()
{
MyNumericClass< int> i = new MyNumericClass< int>();
MyNumericClass< int> j = new MyNumericClass< int>();
MyNumericClass< string> s = new MyNumericClass< string>();
double r1 = i * j;
double r2 = i * s; //运算符'*'不能应用于操作数...
}
}

我需要针对不同的泛型类型进行特定的重载。在这种情况下,非泛型超类将不会执行,因为我有其他操作符重载(此处未显示),如果使用超类型参数而不是确切的泛型类型,则会产生模糊调用。



是否有可能做到这一点或者是否有解决方法?是否可以使用op_Multiply来代替? (尝试过,但无法使其工作)。



我没有看到任何理由为什么这样的事情应该是不可能的。



EDIT1
人们的回答和评论使用隐式强制类型和更多重载添加另一个类的类来演示呼叫歧义,以及为什么提供的答案不能解决我的问题。我需要在运算符重载中指定不同的泛型来解决这个问题:

  public class MyNumericClass< T> 
{
public double Value {get;组; }

public static implicit operator double(MyNumericClass< T> value)
{
return value.Value;
}

公共静态隐式运算符MyNumericClass< T>(double value)
{
MyNumericClass< T> c = new MyNumericClass< T>();
c.Value = value;
return c;
}

public static MyNumericClass< T>运算符*(双左,MyNumericClass< T>右)
{
return left * right.Value;
}

public static MyNumericClass< T> *(MyNumericClass< T> left,double right)
{
return right * left;
}

//不解决歧义,基类或接口也不解释
公共静态双运算符*(MyNumericClass< T>左,动态右)
{
return right * left;
}

//确定,但只适用于相同类型的操作数
public static double operator *(MyNumericClass< T> left,MyNumericClass< T> right)
{
返回left.Value * right.Value;
}

//// ****不同类型操作数的伪代码 - 不行****
//公共静态双操作符*< TRight>( MyNumericClass< T>离开,MyNumericClass< TRight>向右)
// {
//返回left.Value * right.Value;
//}

static void Test()
{
MyNumericClass< int> i = new MyNumericClass< int>();
MyNumericClass< int> j = new MyNumericClass< int>();
MyNumericClass< string> s = new MyNumericClass< string>();
double r1 = i * j;
double r2 = i * s; //这个调用是不明确的......
}
}


解决方案

这实际上取决于您将来如何使用它。

您可以:

包含Value的非泛型基类。然后运算符在基类上工作。



实现一个接口并使用协方差。

像这样:

  void Main()
{
MyNumericClass< int> i = new MyNumericClass< int>();
MyNumericClass< int> j = new MyNumericClass< int>();
MyNumericClass< string> s = new MyNumericClass< string>();

double r1 = i * j;
double r2 = i * s;
}

public interface IMyNumericClass< out T> {
double值{get;组; }
}

公共类MyNumericClass< T> :IMyNumericClass< T>
{
public double Value {get;组; }

public static double operator *(MyNumericClass< T> left,MyNumericClass< T> right)
{
return left.Value * right.Value;
}

public static double operator *(MyNumericClass< T> left,IMyNumericClass< object> right)
{
return left.Value * right.Value;
}
}


There have been a lot of similar questions asked but all involve operands of same type or same generic type. This one in particular (How can I use a generic type parameter with an operator overload?) is close to what I am looking for but no answer or work-around.

Is it possible to do something like this for the ‘*’ operator overload:

public class MyNumericClass<T>
{
    public double Value { get; set; }

    //OK but works only for same type operands
    public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right)
    {
        return left.Value * right.Value;
    }

    //****Pseudo Code for different type operands - not OK****
    public static double operator *<TRight>(MyNumericClass<T> left, MyNumericClass<TRight> right)
    {
        return left.Value * right.Value;
    }

    static void Test()
    {
        MyNumericClass<int> i = new MyNumericClass<int>();
        MyNumericClass<int> j = new MyNumericClass<int>();
        MyNumericClass<string> s = new MyNumericClass<string>();
        double r1 = i * j;
        double r2 = i * s; //Operator '*' cannot be applied to operands...
    }
}

I need to have a specific overload for different generic types. A non-generic superclass will not do in this case as I have other overloads of the operator (not shown here) and ambiguous calls will be produced if I use a parameter of superclass type and not the exact generic type.

Is it possible to do this or is there a work-around? Is it possible to use op_Multiply instead? (Tried it but couldn’t make it work).

P.S. I don’t see any reason why something like this should not be possible.

EDIT1 After people's answers and comments I am adding another version of the class with the implicit casts and more overloads to demonstrate the call ambiguity and why the answers provided do not solve my problem. I need to specify the different generic type in my operator overload to resolve this:

public class MyNumericClass<T>
{
    public double Value { get; set; }

    public static implicit operator double(MyNumericClass<T> value)
    {
        return value.Value;
    }

    public static implicit operator MyNumericClass<T>(double value)
    {
        MyNumericClass<T> c = new MyNumericClass<T>();
        c.Value = value;
        return c;
    }

    public static MyNumericClass<T> operator *(double left, MyNumericClass<T> right)
    {
        return left * right.Value;
    }

    public static MyNumericClass<T> operator *(MyNumericClass<T> left, double right)
    {
        return right * left;
    }

    //Does not resolve ambiguity and neither does a base class or interface
    public static double operator *(MyNumericClass<T> left, dynamic right)
    {
        return right * left;
    }

    //OK but work only for same type operands
    public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right)
    {
        return left.Value * right.Value;
    }

    ////****Pseudo Code for different type operands - not OK****
    //public static double operator *<TRight>(MyNumericClass<T> left, MyNumericClass<TRight> right)
    //{
    //    return left.Value * right.Value;
    //}

    static void Test()
    {
        MyNumericClass<int> i = new MyNumericClass<int>();
        MyNumericClass<int> j = new MyNumericClass<int>();
        MyNumericClass<string> s = new MyNumericClass<string>();
        double r1 = i * j;
        double r2 = i * s; //The call is ambiguous...
    }
}

解决方案

It really depends on how you want to use it in the future.
You can either:

Make a non-generic base class which contains Value. The operator then works on the base class.

Implement an interface and use covariance.

Like this:

void Main()
{
    MyNumericClass<int> i = new MyNumericClass<int>();
    MyNumericClass<int> j = new MyNumericClass<int>();
    MyNumericClass<string> s = new MyNumericClass<string>();

    double r1 = i * j;
    double r2 = i * s; 
}

public interface IMyNumericClass<out T> {
    double Value { get; set; }
}

public class MyNumericClass<T> : IMyNumericClass<T>
{
    public double Value { get; set; }

    public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right)
    {
        return left.Value * right.Value;
    }

    public static double operator *(MyNumericClass<T> left, IMyNumericClass<object> right)
    {
        return left.Value * right.Value;
    }
}

这篇关于如何使用通用类的不同泛型类型的操作数来重载泛型类的操作符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆