通用类,不同类型的运算符重载

时间:2014-10-19 22:02:02

标签: c#

所以,我从C ++转到C#(好吧,不是'移动',而是访问),我试图移植我实践的C ++项目。我似乎找不到任何能引用我特定问题的东西。我有一个模板类Rect -

template< class T >
class Rect
{
public:
    Rect() {}
    Rect( T top, T bottom, T left, T right )
    :
    top( top ),
    bottom( bottom ),
    left( left ),
    right( right )
    {}
    Rect( const Rect& rect )
    :
    top( rect.top ),
    bottom( rect.bottom ),
    left( rect.left ),
    right( rect.right )
    {}
    void Translate( float dx, float dy )
    {
        top += (T)dy;
        bottom += (T)dy;
        left += (T)dx;
        right += (T)dx;
    }
    template< class T2 >
    operator Rect< T2 >() const
    {
        return Rect< int >( (T2) top, (T2)bottom, (T2)left, (T2)right );
    }
    void ClipTo( const Rect& rect )
    {
        top = max( top, rect.top );
        bottom = min( bottom, rect.bottom );
        left = max( left, rect.left );
        right = min( right, rect.right );
    }
public:
    T top;
    T bottom;
    T left;
    T right;
};

问题是Translate(float dx,float dy)方法。我似乎无法在“T&#39;甚至使用&#39; T&#39;键入另一个变量?超载&#39; +&#39;运算符似乎不是答案(同样的问题 - 类型不匹配)。我错过了一些非常简单的事情吗?

2 个答案:

答案 0 :(得分:0)

好..

以下示例中的实际实现非常多余。但我只是展示了扩展方法如何能够解决这个问题(即使只是部分解决)

using System;


namespace FOOBAR
{
class Program
{

    static void Main(string[] args)
    {
        Foo<string> stringFoo = new Foo<string>("this");
        stringFoo.Value = "that";

        Foo<float> floatFoo = new Foo<float>(2f);
        floatFoo.SetFloat(4f);//same as  

    }

}

class Foo<T>
{ 
    T value;
    public T Value { get { return value; } set { this.value = value; } }

    public Foo(T val)
    {
        value = val;
    }
}

public static class FooHelper //this is a class we don't use by itself
{

    //this is an extension method we can use directly from the extended type (Foo<Float>)
    public static void SetFloat(this Foo<float> floatFoo, float value)
    {
        floatFoo.Value = value;//this is redunant unless we do something more complicated
    }
}
}

在visual studio中你会看到

enter image description here

和非浮动foos:

enter image description here

这种特殊用途非常多余。但也许这会给你一些指导。

小心我多年前访问过XNA的c#并且从那时起就没有回到C ++。

答案 1 :(得分:0)

C#不允许在使用泛型时使用算术。解决这个问题的一种方法是使用编译表达式。例如,这里的通用加法器:

public static class Calculator<T>
{
    private static readonly Func<T, T, T> add;

    static Calculator() 
    {
        var param1 = Expression.Parameter(typeof(T));
        var param2 = Expression.Parameter(typeof(T));
        var addLambda = Expression.Lambda<Func<T, T, T>>(
            Expression.Add(param1, param2),
            param1, param2
        );
        add = addLambda.Compile();
    }

    // invoke as Calculator<T>.Add(a, b)
    public static T Add(T a, T b)
    {   
        return add(a, b);
    }
}

这个解决方案有点笨拙,但你只需要编写一次计算器类。您可以使用类似的代码为泛型类型创建其他算术和数学运算符。对于您发布的示例,您还需要一种方法将float转换为T(或者只需更改Translate()以接收T&#39; s)。要进行转换,您可以将以下内容添加到计算器:

private static readonly Func<float, T> fromFloat;

...


// in the static constructor
var floatParameter = Expression.Parameter(typeof(float));
var fromFloatLambda = Expression.Lambda<Func<float, T>>(
    Expression.Convert(floatParameter, typeof(T)),
    floatParameter
);
fromFloat = fromFloatLambda.Compile();


// add a new method
public static T FromFloat(T t) { return fromFloat(t); }