C# 方法能否拒绝Vector2&;的错误类型;矢量3
如果我有一个方法:C# 方法能否拒绝Vector2&;的错误类型;矢量3,c#,unity3d,C#,Unity3d,如果我有一个方法: public void SetPosition(Vector3 position){ // do stuff } 我传递了一个向量2,为什么它仍然允许它并自动转换为(x,y,0) 有没有办法让方法更严格、更错误,而不是自动转换向量?我偶尔会犯这样的错误,但没有意识到这一点,并且会出现一些错误,这些错误需要我花一段时间才能解决 为什么C#甚至允许程序员在传递参数时能够这样做?我不知道是什么库定义了Vector2和Vector3类,但我希望有一个隐式的。此行为已由定义这些
public void SetPosition(Vector3 position){
// do stuff
}
我传递了一个向量2,为什么它仍然允许它并自动转换为(x,y,0)
有没有办法让方法更严格、更错误,而不是自动转换向量?我偶尔会犯这样的错误,但没有意识到这一点,并且会出现一些错误,这些错误需要我花一段时间才能解决
为什么C#甚至允许程序员在传递参数时能够这样做?我不知道是什么库定义了Vector2和Vector3类,但我希望有一个隐式的。此行为已由定义这些类的库实现 一种可能的解决方案是定义第二个位置方法,该方法接受Vector2并抛出:
public void Position(Vector2 position){
throw new InvalidOperationException();
}
我不知道什么库定义了Vector2和Vector3类,但我希望有一个隐式的。此行为已由定义这些类的库实现 一种可能的解决方案是定义第二个位置方法,该方法接受Vector2并抛出:
public void Position(Vector2 position){
throw new InvalidOperationException();
}
您无法修复此问题,因为您正在使用的库提供了转换 Unity为
Vector2
定义了一个隐式转换运算符:
将Vector2
转换为Vector3
Vector2
s可以隐式转换为Vector3
(z
在结果中设置为零)
这与您的观察结果一致:对方法Position
的调用分两步完成-首先,Vector2
转换为Vector3
,并将z
设置为零,然后将结果传递到Position
有一个技巧可以用来击败转换运算符,但它会降低代码的可读性,因此我建议不要使用它。这个想法基于这样一个事实,即C#不会应用两个隐式转换运算符来满足方法调用,因此您可以这样做:
class Vector3Wrap {
private readonly Vector3 v;
private Vector3Wrap(Vector3 v) {
this.v = v;
}
public static implicit operator Vector3Wrap(Vector3 v) {
return new Vector3Wrap(v);
}
public static implicit operator Vector3(Vector3Wrap w) {
return w.v;
}
}
public void SetPosition(Vector3Wrap positionWrap){
Vector3 position = positionWrap;
// do stuff
}
现在对
SetPosition(myVector3)
的调用将成功,因为Vector3Wrap
将被隐式创建,但是调用SetPosition(myVector2)
将失败,因为没有从Vector2
到Vector3Wrap
的隐式转换,您无法修复此问题,因为您正在使用的库提供了一个转换
Unity为Vector2
定义了一个隐式转换运算符:
将Vector2
转换为Vector3
Vector2
s可以隐式转换为Vector3
(z
在结果中设置为零)
这与您的观察结果一致:对方法Position
的调用分两步完成-首先,Vector2
转换为Vector3
,并将z
设置为零,然后将结果传递到Position
有一个技巧可以用来击败转换运算符,但它会降低代码的可读性,因此我建议不要使用它。这个想法基于这样一个事实,即C#不会应用两个隐式转换运算符来满足方法调用,因此您可以这样做:
class Vector3Wrap {
private readonly Vector3 v;
private Vector3Wrap(Vector3 v) {
this.v = v;
}
public static implicit operator Vector3Wrap(Vector3 v) {
return new Vector3Wrap(v);
}
public static implicit operator Vector3(Vector3Wrap w) {
return w.v;
}
}
public void SetPosition(Vector3Wrap positionWrap){
Vector3 position = positionWrap;
// do stuff
}
现在调用SetPosition(myVector3)
将成功,因为Vector3Wrap
将被隐式创建,但是调用SetPosition(myVector2)
将失败,因为没有从Vector2
到Vector3Wrap
的隐式转换
为什么它仍然允许它并自动将其转换为(x,y,0)
原因是Vector2结构的作者编写了一个到Vector3的隐式转换。因为这是Unity3d引擎的一部分,所以您无法真正更改它
有没有办法让方法更严格、更错误,而不是自动转换向量
没有编译器选项可以关闭隐式转换
为什么C#甚至允许程序员在传递参数时能够这样做
它允许类型的作者定义用户不想考虑的“自然”转换。现在,“自然”是一个视角问题。我同意当你认为它们不是自然的时候,它们会变得非常痛苦,所以图书馆的作者必须小心。有。由于Unity3d似乎定义了从Vector3到Vector2的隐式转换,放弃了z分量,因此它们不符合这些要求,这是一个不幸的设计决策。然而,这甚至不是你有问题的转换。无论哪种方式,你都无法摆脱这个库的现状
如果我真的想强制执行不应随意转换为Vector3,我可能会编写某种包装器类型并使用它。一个非常基本的实现是
struct MyVector2
{
private Vector2 _value;
public MyVector2(Vector2 v)
{
_value = v;
}
public Vector2 Value { get { return _value; } }
public Vector3 ToVector3()
{
return Value;
}
public static implicit operator Vector2(MyVector2 v)
{
return v.Value;
}
}
所以这个包装将围绕一个向量2。它允许隐式转换为Vector2,用于任何内置方法,但要传递给Vector3,可以使用ToVector3方法。请注意,该值仍然可以隐式转换,因此请小心使用。同样,这样您就不必在示例中修改设置位置
为什么它仍然允许它并自动将其转换为(x,y,0)
原因是Vector2结构的作者编写了一个到Vector3的隐式转换。因为这是Unity3d引擎的一部分,所以您无法真正更改它
有没有办法让方法更严格、更错误,而不是自动转换向量
没有编译器选项可以关闭隐式转换
为什么C#甚至允许程序员在传递参数时能够这样做
它允许类型的作者定义用户不想考虑的“自然”转换。现在,“自然”是一个视角问题。我同意当你认为它们不是自然的时候,它们会变得非常痛苦,所以图书馆的作者必须小心。有。因为Unity3d似乎定义了隐式转换fr