如何创建对 class 字段的引用?
How to create a reference to a class field?
我的问题是我想创建对 class 字段的引用。 (这样我可以稍后修改引用并在实际的 class 字段中显示结果。)
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
// I would like to make this into a reference type.
Vector3 type;
switch (manipulationInformation.ManipulationType)
{
case "Scale":
type = transform.lossyScale;
break;
case "Rotate":
type = transform.rotation.eulerAngles;
break;
case "Move":
type = transform.position;
break;
}
switch (manipulationInformation.Direction)
{
case 'x':
type = new Vector3(
transform.position.x + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.y,
transform.position.z);
break;
case 'y':
type = new Vector3(
transform.position.x,
transform.position.y + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.z);
break;
case 'z':
type = new Vector3(
transform.position.x,
transform.position.y,
transform.position.z + manipulationInformation.NumericalSign * ModificationIncrement);
break;
}
return transform;
}
与上面的代码一样,'ManipulationInformation' 包含三个 Vector3 字段,对应于 Unity 的变换 class(缩放、位置和旋转)。我希望能够添加和减去这些(因此这里的函数是重载 operator+)。我想将 'type' 变成可以保存对变换的 Vector3 之一的引用的东西,这样我就可以简化我的代码。 (一个肯定但丑陋的选择是在 'switch(manipulationInformation.ManipulationType)' 语句的每个 case 中放置一个 'switch(manipulationInformation.Direction)' 语句;然而,代码量随着 case 语句的增加呈指数级增长,而且可读性不佳。
我想知道是否有解决这种疯狂的办法。提前感谢大家!
编辑:我的意思是 'type' 是对变换的缩放、旋转和位置字段之一的引用。并使对类型的修改也将修改转换的字段。但是,我现在明白这不是必需的,我的问题是由于其他原因造成的。谢谢 Kevin Gosse。
您的方法有两个不同的部分:实际计算和赋值。您可以通过提取方法使您的代码更容易 read/maintain:
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
var type = ApplyManipulation(manipulationInformation, transform.position);
switch (manipulationInformation.ManipulationType)
{
case "Scale":
transform.lossyScale = type;
break;
case "Rotate":
transform.eulerAngles = type;
break;
case "Move":
transform.position = type;
break;
}
return transform;
}
private static Vector3 ApplyManipulation(ManipulationInformation manipulationInformation, Vector3 position)
{
var offset = manipulationInformation.NumericalSign * ModificationIncrement;
switch (manipulationInformation.Direction)
{
case 'x':
return new Vector3(
position.x + offset,
position.y,
position.z);
case 'y':
return new Vector3(
position.x,
position.y + offset,
position.z);
case 'z':
return new Vector3(
position.x,
position.y,
position.z + offset);
}
throw new InvalidOperationException("Unknown direction: " + manipulationInformation.Direction);
}
其实ApplyManipulation
方法应该直接在ManipulationInformation
class中声明。这是一种称为 feature envy 的代码味道。从那里开始,两种类型都可以单独发展,您的代码将变成:
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
var type = manipulationInformation.Apply(transform.position, ModificationIncrement);
switch (manipulationInformation.ManipulationType)
{
case "Scale":
transform.lossyScale = type;
break;
case "Rotate":
transform.eulerAngles = type;
break;
case "Move":
transform.position = type;
break;
}
return transform;
}
您可以通过引入第三种类型来进一步减少耦合,这种类型知道如何在 Transform
上应用 ManipulationInformation
(整个 switch (manipulationInformation.ManipulationType)
代码),但这可能有点矫枉过正那一点。
我认为您 +
超载了太多。如果你不关心这个,那就继续往下看。
你可能应该这样做:
Action<Transform, Vector3> action;
switch (manipulationInformation.ManipulationType)
{
case "Scale":
action = (t, v) => t.lossyScale = v;
break;
case "Rotate":
action = (t, v) => t.rotation.eulerAngles = v;
break;
case "Move":
action = (t, v) => t.position = v;
break;
}
switch (manipulationInformation.Direction)
{
case 'x':
action(transform, new Vector3(
transform.position.x + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.y,
transform.position.z));
break;
case 'y':
action(transform, new Vector3(
transform.position.x,
transform.position.y + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.z));
break;
case 'z':
action(transform, new Vector3(
transform.position.x,
transform.position.y,
transform.position.z + manipulationInformation.NumericalSign * ModificationIncrement));
break;
}
因为 transform
不是值类型,它可以被传递,所以你可以用一些委托魔法来做到这一点。
我的问题是我想创建对 class 字段的引用。 (这样我可以稍后修改引用并在实际的 class 字段中显示结果。)
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
// I would like to make this into a reference type.
Vector3 type;
switch (manipulationInformation.ManipulationType)
{
case "Scale":
type = transform.lossyScale;
break;
case "Rotate":
type = transform.rotation.eulerAngles;
break;
case "Move":
type = transform.position;
break;
}
switch (manipulationInformation.Direction)
{
case 'x':
type = new Vector3(
transform.position.x + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.y,
transform.position.z);
break;
case 'y':
type = new Vector3(
transform.position.x,
transform.position.y + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.z);
break;
case 'z':
type = new Vector3(
transform.position.x,
transform.position.y,
transform.position.z + manipulationInformation.NumericalSign * ModificationIncrement);
break;
}
return transform;
}
与上面的代码一样,'ManipulationInformation' 包含三个 Vector3 字段,对应于 Unity 的变换 class(缩放、位置和旋转)。我希望能够添加和减去这些(因此这里的函数是重载 operator+)。我想将 'type' 变成可以保存对变换的 Vector3 之一的引用的东西,这样我就可以简化我的代码。 (一个肯定但丑陋的选择是在 'switch(manipulationInformation.ManipulationType)' 语句的每个 case 中放置一个 'switch(manipulationInformation.Direction)' 语句;然而,代码量随着 case 语句的增加呈指数级增长,而且可读性不佳。
我想知道是否有解决这种疯狂的办法。提前感谢大家!
编辑:我的意思是 'type' 是对变换的缩放、旋转和位置字段之一的引用。并使对类型的修改也将修改转换的字段。但是,我现在明白这不是必需的,我的问题是由于其他原因造成的。谢谢 Kevin Gosse。
您的方法有两个不同的部分:实际计算和赋值。您可以通过提取方法使您的代码更容易 read/maintain:
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
var type = ApplyManipulation(manipulationInformation, transform.position);
switch (manipulationInformation.ManipulationType)
{
case "Scale":
transform.lossyScale = type;
break;
case "Rotate":
transform.eulerAngles = type;
break;
case "Move":
transform.position = type;
break;
}
return transform;
}
private static Vector3 ApplyManipulation(ManipulationInformation manipulationInformation, Vector3 position)
{
var offset = manipulationInformation.NumericalSign * ModificationIncrement;
switch (manipulationInformation.Direction)
{
case 'x':
return new Vector3(
position.x + offset,
position.y,
position.z);
case 'y':
return new Vector3(
position.x,
position.y + offset,
position.z);
case 'z':
return new Vector3(
position.x,
position.y,
position.z + offset);
}
throw new InvalidOperationException("Unknown direction: " + manipulationInformation.Direction);
}
其实ApplyManipulation
方法应该直接在ManipulationInformation
class中声明。这是一种称为 feature envy 的代码味道。从那里开始,两种类型都可以单独发展,您的代码将变成:
public static Transform operator +(Transform transform, ManipulationInformation manipulationInformation)
{
var type = manipulationInformation.Apply(transform.position, ModificationIncrement);
switch (manipulationInformation.ManipulationType)
{
case "Scale":
transform.lossyScale = type;
break;
case "Rotate":
transform.eulerAngles = type;
break;
case "Move":
transform.position = type;
break;
}
return transform;
}
您可以通过引入第三种类型来进一步减少耦合,这种类型知道如何在 Transform
上应用 ManipulationInformation
(整个 switch (manipulationInformation.ManipulationType)
代码),但这可能有点矫枉过正那一点。
我认为您 +
超载了太多。如果你不关心这个,那就继续往下看。
你可能应该这样做:
Action<Transform, Vector3> action;
switch (manipulationInformation.ManipulationType)
{
case "Scale":
action = (t, v) => t.lossyScale = v;
break;
case "Rotate":
action = (t, v) => t.rotation.eulerAngles = v;
break;
case "Move":
action = (t, v) => t.position = v;
break;
}
switch (manipulationInformation.Direction)
{
case 'x':
action(transform, new Vector3(
transform.position.x + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.y,
transform.position.z));
break;
case 'y':
action(transform, new Vector3(
transform.position.x,
transform.position.y + manipulationInformation.NumericalSign * ModificationIncrement,
transform.position.z));
break;
case 'z':
action(transform, new Vector3(
transform.position.x,
transform.position.y,
transform.position.z + manipulationInformation.NumericalSign * ModificationIncrement));
break;
}
因为 transform
不是值类型,它可以被传递,所以你可以用一些委托魔法来做到这一点。