user1075940
user1075940

Reputation: 1125

specific class variable value in generic method

in my program I have following code:

 private void SetCorners<T>(T position, int width, int height)
    {
        float halfWidth = width / 2 + position.X;
        float halfHeight = height / 2 + position.Y;

        UpperLeft = new Vector2(-halfWidth, -halfHeight);
        UpperRight = new Vector2(halfWidth, -halfHeight);
        LowerLeft = new Vector2(-halfWidth, halfHeight);
        LowerRight = new Vector2(halfWidth, halfHeight);
    }

In which T is either Vector2 or Vector3 from Microsoft.Xna.Framework. This code does not build because T does not contains definition of them.How to make this method works?

Upvotes: 0

Views: 70

Answers (4)

Alex Filipovici
Alex Filipovici

Reputation: 32551

You could also create a wrapper class for the two structs:

private void SetCorners<T>(T position, int width, int height)
    where T : MyVectorWrapper
{
    float halfWidth = width / 2 + position.X;
    float halfHeight = height / 2 + position.Y;

    UpperLeft = new Vector2(-halfWidth, -halfHeight);
    UpperRight = new Vector2(halfWidth, -halfHeight);
    LowerLeft = new Vector2(-halfWidth, halfHeight);
    LowerRight = new Vector2(halfWidth, halfHeight);
}

class MyVectorWrapper
{
    public float X { get; set; }
    public float Y { get; set; }

    public MyVectorWrapper(dynamic vector2)
    {
        X = vector2.X;
        Y = vector2.Y;
    }
}

Sample usage:

var v2 = new Vector2(1, 2);
var v3 = new Vector3(v2, 3);
SetCorners<MyVectorWrapper>(new MyVectorWrapper(v2), width, height);
SetCorners<MyVectorWrapper>(new MyVectorWrapper(v3), width, height);

Upvotes: 1

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174299

Because there is no common base-class or interface that both Vector2 and Vector3 derive from or implement, you would create a method that takes X and Y directly and create two helper methods that call this new method:

private void SetCorners(Vector2 position, int width, int height)
{
    SetCorners(position.X, position.Y, width, height);
}

private void SetCorners(Vector3 position, int width, int height)
{
    SetCorners(position.X, position.Y, width, height);
}

private void SetCorners(float x, float y, int width, int height)
{
    float halfWidth = width / 2 + x;
    float halfHeight = height / 2 + y;

    UpperLeft = new Vector2(-halfWidth, -halfHeight);
    UpperRight = new Vector2(halfWidth, -halfHeight);
    LowerLeft = new Vector2(-halfWidth, halfHeight);
    LowerRight = new Vector2(halfWidth, halfHeight);
}

This allows you to not repeat yourself (DRY) but still support both Vector2 and Vector3.

Upvotes: 3

robert.oh.
robert.oh.

Reputation: 666

I don't know if Vector2 and Vector3 have some common interface or base class but you could add a constraint to your generic method like so:

private void Method<T>(T bla)
  where T : BaseInterfaceOrBaseClass
{ ... }

Upvotes: 0

jdehaan
jdehaan

Reputation: 19928

I would then write two separate methods, one for Vector2 and one for Vector3. Generally speaking you could use a generic type constraint but I think this would be a bit too artificial here.

Upvotes: 0

Related Questions