向C#结构添加功能 [英] Adding Functionality to C# Structures

查看:67
本文介绍了向C#结构添加功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到如何向C#结构中添加功能,而不仅仅是将它们包装在全新的类中,而是一种更为优雅的方式。扩展方法不像覆盖方法那么强大,而且绝对不能提供结构事件触发/处理功能。

I'm trying to find how to add functionality to C# structures, and in a more elegant way than just wrapping them in entirely new classes. An extension method just isn't as powerful as an override, and most definitely cannot give a struct event firing/handling capabilities either.

我目前面临的特定问题但是,它正在检测Vector2结构的成员并对其做出反应。不过,这只是一个内部要求,因此,我的库的用户在与Vector2结构进行交互时(仍会引发内部事件)应该只能使用/感知Vector2结构。

The specific problem I'm currently facing however is detecting and reacting to changes in a Vector2 structure's members. This is only an internal requirement though, so users of my library should be able to use/perceive only Vector2 structures when interacting with it (while still setting off internal events).

通常,除了扩展方法或封装之外,如何扩展C#结构?

具体来说,如何扩展Vector2结构以支持事件触发/处理?

推荐答案


通常,除了扩展
方法或封装之外,我如何扩展C#结构?

Generally, how can I extend C# structures other than by extension methods or encapsulation?

唯一的方法是创建扩展方法或使用封装。

The only way is to create extension methods or use encapsulation.


我扩展了Vector2结构以支持事件
触发/处理?

Specifically, how can I extend the Vector2 structure to support event firing/handling?

正如我之前所说的,您可以使用封装和创建课程。因此,使用以下代码:

As I said previously you can use encapsulation and create a class. So use this code:

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);
    }
}

然后您可以添加接口,方法和事件。

Then you can add interfaces, methods and events.

编辑:


但是我如何检测X或Y是否改变?假设用户获取
向量,然后设置其成员之一(X或Y)。我可以在设置Vector整体时触发事件
触发,但是当其中的一个
成员在获取之后设置时触发事件。请记住,我不想强​​迫
用户使用新的向量类以便与我的
库进行交互。我什至不希望他/她必须知道内部正在使用新的vector
类。

But how would I detect if X or Y changes? Say the user "gets" the Vector, and then sets one of its members (X or Y). I could add event firing for when the Vector as a whole is set, but not when one of it's members are set after a 'get.' Keep in mind that I don't want to force the user to use a new vector class in order to interact with my library. I don't even want him/her to have to know that a new vector class is being used internally.

首先,如果要完全屏蔽内部使用的类型为 Vector2 的结构,则应以这种方式重写所有方法:

Firstly if you want to mask completely that internally is used a structure of type Vector2 you should rewrite all methods in this way:

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。让我们写一些代码:

Now it's simple if you want to create an event that is fired when one members changes. I'd create a costumized EventArgs. Let's write some code:

//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;
    }
}

然后您可以编写自己的事件:

Then you can write your own event:

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
}

这篇关于向C#结构添加功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆