Я хочу минимизировать копирование структур в математической библиотеке и прочитать о модификаторе C # 7.2 in
, особенно о предупреждениях при использовании его с изменяемым структурами.
Это так происходитчто у меня есть эта изменчивая структура:
public struct Quaternion
{
public float W;
public float X;
public float Y;
public float Z;
}
Пока что в библиотеке есть такие методы, где параметры передаются ref
:
public static void Dot(ref Quaternion left, ref Quaternion right, out float result)
=> result = left.W * right.W + left.X * right.X + left.Y * right.Y + left.Z * right.Z;
Из документации MSDN яузнал, что если я изменю их на in
параметры, при условии, что я только получаю доступ к полям изменяемой структуры, защитная копия не произойдет, так как компилятор видит, что я не изменяю изменяемую структуру:
public static void Dot(in Quaternion left, in Quaternion right, out float result)
=> result = left.W * right.W + left.X * right.X + left.Y * right.Y + left.Z * right.Z;
Первый вопрос: верно ли мое понимание этого поведения?
Второй, глупый вопрос: Если в одном из таких методов, которые принимают структуру в качестве параметра in
, будет лископировать его, если я вызову другой метод, принимающий их как in
параметры? Пример:
public static void Lerp(in Quaternion start, in Quaternion end, float amount,
out Quaternion result)
{
float inv = 1.0f - amount;
if (Dot(start, end) >= 0.0f) // will 2 copies be created here?
{
result.W = inv * start.W + amount * end.W;
result.X = inv * start.X + amount * end.X;
result.Y = inv * start.Y + amount * end.Y;
result.Z = inv * start.Z + amount * end.Z;
}
else
{
result.W = inv * start.W - amount * end.W;
result.X = inv * start.X - amount * end.X;
result.Y = inv * start.Y - amount * end.Y;
result.Z = inv * start.Z - amount * end.Z;
}
result.Normalize();
}
Я почти уверен, что не создает копии - как иначеЯ предэнт копии со стороны вызова тогда? Но поскольку я не уверен, лучше сначала спросить, прежде чем создавать беспорядок.
Приложение
Причины, по которым я хочу изменить ref
на in
:
- (
static
) readonly
поля (например, конкретные постоянные кватернионы) не могут быть переданы как ref
аргументы. - Я не могу указать
ref
для параметров оператора,но я могу использовать in
. - Постоянно указывать
ref
на сайте вызовов ужасно. - Я знаю, что мне нужно везде менять сайт вызовов, но это нормально, так какэта библиотека будет использоваться только для внутреннего использования.