C# 财产实施-Noob缺乏知识
我相信这个问题以前已经回答过对不起,但我不能把我的问题浓缩成一个愚蠢的短语 我有一个Pt3类,它是一个3d笛卡尔点(x,y,z属性加上一些其他的好东西)。我使用Pt3类型作为RegionProvider类中的get/set属性值-用于Location和Normal Location属性很好,我不在乎如何设置属性:C# 财产实施-Noob缺乏知识,c#,properties,C#,Properties,我相信这个问题以前已经回答过对不起,但我不能把我的问题浓缩成一个愚蠢的短语 我有一个Pt3类,它是一个3d笛卡尔点(x,y,z属性加上一些其他的好东西)。我使用Pt3类型作为RegionProvider类中的get/set属性值-用于Location和Normal Location属性很好,我不在乎如何设置属性: //Location set method 1 - sweet... RegionProvider Foo = new RegionProvider(); Foo.Location.x
//Location set method 1 - sweet...
RegionProvider Foo = new RegionProvider();
Foo.Location.x = 10;
Foo.Location.y = 20;
Foo.Location.z = 30;
//Location set method 2 - also sweet...
RegionProvider Foo2 = new RegionProvider();
Foo2.Location = new Pt3(10, 20, 30);
不过,普通属性需要不同的行为。如果需要,我希望RegionProvider类将输入规范化为Normal属性,例如,如果调用方将“Normal”值设置为40,50,60,RegionProvider类将规范化为0.4558、0.5698、0.6838(给出向量长度==1)。如果来电者执行以下操作,则一切正常
//Normal set method A - sweet...
Foo.Normal = new Pt3(40, 50, 60);
…但如果他们这样做会带来悲伤:
//Normal set method B - grief...
Foo2.Normal.x = 40;
Foo2.Normal.y = 50;
Foo2.Normal.z = 60;
…因为RegionProvider类将随着每个元素的设置而规范化。我想做的是防止调用方看到Normal属性的x,y,z,所以他们被迫使用上面的方法“A”
一种解决方案可能是根本不规范属性集,而是规范化属性get,但这似乎是伪造的
值得一提的是,这是我的正常财产声明:
/// <summary>
/// Property for the objects normal
/// </summary>
public Pt3 Normal
{
set
{
_normal = Bit555ModelCore.NormalizeVector(value);
this.NotifyPropertyChanged("Normal");
}
get
{
return _normal;
}
}
//
///法线对象的属性
///
公共Pt3正常
{
设置
{
_normal=位555ModelCore.NormalizeVector(值);
本条。NotifyPropertyChanged(“正常”);
}
收到
{
恢复正常;
}
}
为任何帮助提前欢呼。如果Pt3是你的职业,移除setter,(X,Y,Z)或将其设置为私有。如果Pt3是你的职业,移除setter,(X,Y,Z)或将其设置为私有。假设
正常和位置必须是相同的类型,Pt3可以具有简单的属性:
public bool CanSetXyz { get; }
private int _x;
public int X
{
get { return _x; }
set
{
if (!CanSetXyz)
{
throw new CantSetXyzException("Can't set X on a Normal point.");
}
_x = value;
}
}
对于位置
,将此属性初始化为true
。对于Normal
,将其初始化为false
然后在每个X、Y和Z属性中:
public bool CanSetXyz { get; }
private int _x;
public int X
{
get { return _x; }
set
{
if (!CanSetXyz)
{
throw new CantSetXyzException("Can't set X on a Normal point.");
}
_x = value;
}
}
如果它们不必是相同的类型,您可能希望创建一个公共基类,其中包含始终在这两个类之间共享的内容,然后一个类将没有X、Y和Z的设置器,而另一个类将具有公共设置器
例如:
public abstract class BasePt3
{
protected int x;
}
public class LocationPt3 : BasePt3
{
public int X
{
get { return x; }
set { x = value; }
}
public LocationPt3(int _x)
{
x = _x;
}
}
public class NormalPt3 : BasePt3
{
public int X
{
get { return x; }
}
public NormalPt3(int _x)
{
x = _x;
}
}
EDIT:一个可能更有用的示例,基类允许读取X:
public abstract class BasePt3
{
protected int x;
public int X
{
get { return x; }
}
}
public class LocationPt3 : BasePt3
{
public new int X
{
get { return x; }
set { x = value; }
}
public LocationPt3(int _x)
{
x = _x;
}
}
public class NormalPt3 : BasePt3
{
public new int X
{
get { return x; }
}
public NormalPt3(int _x)
{
x = _x;
}
}
假设Normal
和Location
必须为同一类型,Pt3可以具有简单的属性:
public bool CanSetXyz { get; }
private int _x;
public int X
{
get { return _x; }
set
{
if (!CanSetXyz)
{
throw new CantSetXyzException("Can't set X on a Normal point.");
}
_x = value;
}
}
对于位置
,将此属性初始化为true
。对于Normal
,将其初始化为false
然后在每个X、Y和Z属性中:
public bool CanSetXyz { get; }
private int _x;
public int X
{
get { return _x; }
set
{
if (!CanSetXyz)
{
throw new CantSetXyzException("Can't set X on a Normal point.");
}
_x = value;
}
}
如果它们不必是相同的类型,您可能希望创建一个公共基类,其中包含始终在这两个类之间共享的内容,然后一个类将没有X、Y和Z的设置器,而另一个类将具有公共设置器
例如:
public abstract class BasePt3
{
protected int x;
}
public class LocationPt3 : BasePt3
{
public int X
{
get { return x; }
set { x = value; }
}
public LocationPt3(int _x)
{
x = _x;
}
}
public class NormalPt3 : BasePt3
{
public int X
{
get { return x; }
}
public NormalPt3(int _x)
{
x = _x;
}
}
EDIT:一个可能更有用的示例,基类允许读取X:
public abstract class BasePt3
{
protected int x;
public int X
{
get { return x; }
}
}
public class LocationPt3 : BasePt3
{
public new int X
{
get { return x; }
set { x = value; }
}
public LocationPt3(int _x)
{
x = _x;
}
}
public class NormalPt3 : BasePt3
{
public new int X
{
get { return x; }
}
public NormalPt3(int _x)
{
x = _x;
}
}
Pt3
可能应该是一个结构,并被视为一个不可变的值
移除设置器,只允许通过构造函数设置坐标。您类型的用户将无法一次更改一个属性,RegionProvider
将始终知道Normal
的值何时更改
这就是基本的行为方式,除了点
允许设置X和Y,当人们尝试类似的事情时,会导致各种各样的问题
Foo.Bar.X += 10;
而不是
Foo.Bar += new Size(10, 0);
Pt3
可能应该是一个结构,并被视为一个不可变的值
移除设置器,只允许通过构造函数设置坐标。您类型的用户将无法一次更改一个属性,RegionProvider
将始终知道Normal
的值何时更改
这就是基本的行为方式,除了点
允许设置X和Y,当人们尝试类似的事情时,会导致各种各样的问题
Foo.Bar.X += 10;
而不是
Foo.Bar += new Size(10, 0);
我想说问题在于你关于“好东西”的说法
如果您决定要有一个向量类(您的Pt3),那么就这样使用它。定义“Normalize()”方法并显式使用它
不管怎样,这就是我的建议。我想说问题在于你关于“好东西”的说法
如果您决定要有一个向量类(您的Pt3),那么就这样使用它。定义“Normalize()”方法并显式使用它
嗯,无论如何,这是我的建议。我想你有两个选择:
通过使整个类不可变,确保从不单独设置Pt3
的属性:
class Pt3
{
public Pt3(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public double X { get; private set; }
public double Y { get; private set; }
public double Z { get; private set; }
}
有两个类:Pt3Mutable
和Pt3Immutable
(或一些更好的名称)Pt3Immutable
将是不可变的,因此您可以安全地将其用于Normal
Pt3Mutable
是可变的,所以如果将其用于位置
,方法1仍然可以工作
然后,您可以使用强制转换运算符在两种类型之间进行转换:隐式强制转换从Pt3Mutable
转换为Pt3Immutable
,而显式强制转换则相反
我认为你有两个选择:
通过使整个类不可变,确保从不单独设置Pt3
的属性:
class Pt3
{
public Pt3(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public double X { get; private set; }
public double Y { get; private set; }
public double Z { get; private set; }
}
有两个类:Pt3Mutable
和Pt3Immutable
(或一些更好的名称)Pt3Immutable
将是不可变的,因此您可以安全地将其用于Normal
Pt3Mutable
是可变的,所以如果将其用于位置
,方法1仍然可以工作
然后,您可以使用强制转换运算符在两种类型之间进行转换:隐式强制转换从Pt3Mutable
转换为Pt3Immutable
,而显式强制转换则相反
标准的.NET陷阱,绝不是同样的方式,alw