Условно необязательные параметры для устранения перегрузок - PullRequest
1 голос
/ 10 февраля 2012

У меня есть следующие методы C #:

public Vector2 GetVectorToTile(int x, int y)
    {
        return new Vector2(x * TileWidth, y * TileHeight);
    }
public Vector2 GetVectorToTile(Point start)
    {
        return GetVectorToTile(start.X, start.Y);
    }

Второй метод очень просто перегружает первый.Однако мне не очень нравится такая «перегрузка дезинфицирующего средства ввода» - я чувствую, что не должно быть отдельного метода для преобразования каждого возможного типа ввода.

Теперь, если вход первого метода былодиночное Vector2 вместо двух чисел, я мог бы использовать условные аргументы, так что если аргумент Point вместо Vector2, он должен сначала преобразовать из Point в Vector2, а затем продолжить как обычно.

Однако это не так.

Итак, мой вопрос: как я могу сказать методу, чтобы он принимал «ЛИБО два целых ИЛИ одну точку», а затем преобразовал последние в первое, прежде чем вычислятьрезультат?

Я могу сделать это искусственно в Matlab, но это выглядит совершенно не связанным с C #:

function result = VectorToTile(varargin)
    x = 0;
    y = 0;

    if size(varargin{1}) == [1, 1]
        disp('Assuming Vector input!');
        x = varargin{1}{1}.x; % Assuming the "Vector2" equivalent is a struct with .x and .y
        y = varargin{1}{1}.y;
    else
        disp('Assuming integer pair input!');
        x = varargin{1}{1};
        y = varargin{1}{2};
    end

    result.x = x * 32; % An example value for TileWidth
    result.y = y * 32; % An example value for TileHeight
end

Это будет работать со следующими двумя входами:

ints{1} = 25;
ints{2} = 125;
VectorToTile(ints);

vect{1}.x = 25;
vect{1}.y = 125;
VectorToTile(vect);

Это иллюстрирует то, что я хочу сделать, но, к сожалению, в C # на самом деле нет varargin, и все не рассматривается как матрица.

Ответы [ 3 ]

6 голосов
/ 10 февраля 2012

Я не хочу показаться легкомысленным, но:

Итак, мой вопрос, как я могу сказать методу, чтобы он принимал "ЛИБО два целых ИЛИ одну точку", а затем преобразовал последнийв первое, прежде чем вычислить результат?

вот так:

public Vector2 GetVectorToTile(int x, int y)
{
    return new Vector2(x * TileWidth, y * TileHeight);
}
public Vector2 GetVectorToTile(Point start)
{
    return GetVectorToTile(start.X, start.Y);
}

разве код, который вы опубликовали, делает именно то, что вы хотите?и намного чище, безопаснее, чем в примере с Matlab, который вы опубликовали .. (ИМХО)

2 голосов
/ 10 февраля 2012

Вы могли бы :

public Vector2 GetVectorToTile(int? x = null, int? y = null, Point? start = null)  
{
    Vector2 vector = null;
    if (x.HasValue && y.HasValue)
    {
        vector = new Vector2(x * TileWidth, y * TileHeight);         
    }
    else if(start.HasValue)
    {
        vector = new Vector2(start.X * TileWidth, start.Y * TileHeight); 
    }

    return vector;
}

Но согласитесь с Сэмом Холдером, я думаю, что вы делаете хорошо в C #.Выше выглядит грязно и, вероятно, более склонны к ошибкам, чем ваш подход.Например, что если вы предоставите все 3 аргумента, которые будут иметь приоритет?и т.д.

1 голос
/ 10 февраля 2012

Вы можете использовать массив параметров params ключевое слово для передачи в массив объектов.

Например:

public Vector2 GetVectorToTile(params object[] args)

Затем вы можете проверить, сколько в вашем массиве и обработать соответственно,

Но уж точно строго типизированные параметры лучше?

...