所以,我从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;运算符似乎不是答案(同样的问题 - 类型不匹配)。我错过了一些非常简单的事情吗?
答案 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中你会看到
和非浮动foos:
这种特殊用途非常多余。但也许这会给你一些指导。
小心我多年前访问过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); }