我试图找到如何向 C# 结构添加功能,并且以一种比将它们包装在全新类中更优雅的方式。扩展方法没有覆盖那么强大,而且绝对不能提供结构事件触发/处理能力。
然而,我目前面临的具体问题是检测 Vector2 结构成员的变化并做出反应。不过,这只是一个内部要求,因此我的库的用户在与它交互时应该能够使用/感知 Vector2 结构(同时仍会触发内部事件)。
通常,除了扩展方法或封装之外,我如何扩展 C# 结构?
具体来说,如何扩展 Vector2 结构以支持事件触发/处理?
我试图找到如何向 C# 结构添加功能,并且以一种比将它们包装在全新类中更优雅的方式。扩展方法没有覆盖那么强大,而且绝对不能提供结构事件触发/处理能力。
然而,我目前面临的具体问题是检测 Vector2 结构成员的变化并做出反应。不过,这只是一个内部要求,因此我的库的用户在与它交互时应该能够使用/感知 Vector2 结构(同时仍会触发内部事件)。
通常,除了扩展方法或封装之外,我如何扩展 C# 结构?
具体来说,如何扩展 Vector2 结构以支持事件触发/处理?
通常,除了扩展方法或封装之外,我如何扩展 C# 结构?
唯一的方法是创建扩展方法或使用封装。
具体来说,如何扩展 Vector2 结构以支持事件触发/处理?
正如我之前所说,您可以使用封装并创建一个类。所以使用这个代码:
public class ExtendedVector2 {
public Vector2 Vector{
get;
private set;
}
public ExtendedVector2(float value){
Vector = new Vector2(value);
}
public ExtendedVector2(float x, float y){
Vector = new Vector2(x, y);
}
}
然后你可以添加接口、方法和事件。
编辑 :
但是我如何检测 X 或 Y 是否发生变化?假设用户“获取”了 Vector,然后设置其成员之一(X 或 Y)。我可以在设置整个向量时添加事件触发,但不能在“获取”之后设置其中一个成员时添加事件触发。请记住,我不想强迫用户使用新的矢量类来与我的库进行交互。我什至不希望他/她知道内部正在使用一个新的向量类。
首先,如果您想完全掩盖内部使用的类型结构,Vector2
您应该以这种方式重写所有方法:
public class ExtendedVector2 {
//...
private Vector2 _vector2;
//mask X and Y values of Vector2 structure
public float X{
set{ _vector2.X = value; }
get{ return _vector2.X; }
}
public float Y{
set{ _vector2.Y = value; }
get{ return _vector2.Y; }
}
//example to mask a method of Vector2 structure
public static float Dot(ExtendedVector2 value1, ExtendedVector2 value2){
return Vector.Dot(value1, value2);
}
//override the cast to Vector2
public static implicit operator Vector2(ExtendedVector2 value) //I'd make it implicit because I'd think to it like an upcast
{
return new Vector2(value.X, value.Y);
}
}
更多信息请看这里。
现在,如果您想创建一个在成员更改时触发的事件,这很简单。我会创建一个定制的 EventArgs。让我们写一些代码:
//use the convention of eventName+EventArgs
class MemberChangedEventArgs : EventArgs
{
public readonly float LastValue{
get;
set;
}
public readonly float NewValue{
get;
set;
}
public MemberChangedEventArgs(float LastValue, float NewValue)
{
this.LastValue = LastValue;
this.NewValue = NewValue;
}
}
然后你可以编写自己的事件:
public class ExtendedVector2 {
private Vector2 _vector2;
public float X{
set{
if(_vector2.X != value)
OnMemberXChanged(new MemberChangedEventArgs(_vector2.X, value));
_vector2.X = value;
}
get{ return _vector2.X; }
}
public float Y{
set{
if(_vector2.Y != value)
OnMemberYChanged(new MemberChangedEventArgs(_vector2.Y, value));
_vector2.Y = value;
}
get{ return _vector2.Y; }
}
public event EventHandler<MemberChangedEventArgs> MemberXChanged;
public event EventHandler<MemberChangedEventArgs> MemberYChanged;
public ExtendedVector2(float value){
Vector = new Vector2(value);
}
public ExtendedVector2(float x, float y){
Vector = new Vector2(x, y);
}
private virtual void OnMemberXChanged(MemberChangedEventArgs e){
if(MemberXChanged != null)
MemberXChanged(this, e);
}
private virtual void OnMemberYChanged(MemberChangedEventArgs e){
if(MemberYChanged != null)
MemberYChanged(this, e);
}
//...
//here mask the Vector2 structure using the previous solution
}