首页 > 解决方案 > 拥有一个具有不同方法操作的类 - 虚拟还是委托?

问题描述

我在 C# 中有一个Item类,我想要两个方法,OnRightClickOnLeftClick,但我希望每个项目在使用它们时做不同的事情(我在 Unity 上,这个类不是 monoBehavior)。

我听说过virtual方法,但据我所知,它们只能从继承它们的其他类中被覆盖。但是,我不想为我制作的每件商品单独创建一个类。我怎样才能使这两种方法有所不同?

我想过使用delegate,但它也没有按我预期的方式工作。甚至可能吗?

编辑

(我认为以下行不是一回事,但这是我能以某种方式解释我想要做什么的最佳方式)

想象一下有以下简单的类 Item

public class Item
{
    private string name;
    private float weight;
    private int price;
    private bool dropable;

    public Item(string name, float weight, int price, bool dropable)
    {
        this.name = name;
        this.weight = weight;
        this.price = price;
        this.dropable = dropable;
    }

    public Item(string name, float weight, int price)
    {
        this.name = name;
        this.weight = weight;
        this.price = price;
        this.dropable = true;
    }

    public string GetName()
    {
        return this.name;
    }

    public float GetWeight()
    {
        return this.weight;
    }

    public int GetPrice()
    {
        return this.price;
    }

    public bool GetDropable()
    {
        return this.dropable;
    }

    public void SetDropable(bool dropable)
    {
        this.dropable = dropable;
    }
}

我希望能够制作一个 OnRightClick 和 OnLeftClick ,如果我可以做类似的事情,我创建的每个项目都会有所不同(正如我所说我知道它无效但这是我可以解释它的最佳方式,也没有提到它在上面的类中,这是我目前拥有的原始类)

Item item1 = new Item(*all the stuff here*);
Item item2 = new Item(*other stuff*);
item1.OnRightClick = delegate {*what I want on right click*};
item1.OnRightClick(); //executes the function for item1
item2.OnRightClick = delegate {*other stuff on right click*};
item2.OnRightClick(); //executes a different function for item2

同样,这不是一个有效的代码,但我只是用它来尝试解释我想要尝试和做的事情,并询问是否存在任何解决方案。在最坏的情况下,如果没有,我可以只使用 virtual,但我希望这是我最后一个别无选择的情况。

标签: c#unity3d

解决方案


您可以使用 Action 和 Func 来完成您的要求。

https://docs.microsoft.com/en-us/dotnet/api/system.action-1?view=netcore-3.1

https://docs.microsoft.com/en-us/dotnet/api/system.func-2?view=netcore-3.1

public enum ItemType
{
    Sword,
    Shield,
    Potion
}

public class Item
{
    private readonly Action leftClickHandler;
    private readonly Action<int> leftClickHandlerWithParam;
    private readonly Action rightClickHandler;
    private readonly Action<int> rightClickHandlerWithParam;

    public Item(ItemType itemType)
    {
        switch (itemType)
        {
            case ItemType.Potion:
                this.rightClickHandler = this.HandleClickWithFlash;
                this.leftClickHandler = this.HandleClickWithSound;

                this.leftClickHandlerWithParam = this.HandleClickWithFlash;
                this.rightClickHandlerWithParam = this.HandleClickWithSound;
                break;
        }
    }

    public void HandleLeftClick()
    {
        this.leftClickHandler();
    }

    public void HandleRightClick()
    {
        this.rightClickHandler();
    }

    private void HandleClickWithFlash()
    {
        // Logic here.
    }

    private void HandleClickWithFlash(int parameter)
    {
        // Logic here.
    }

    private void HandleClickWithSound()
    {
        // Logic here.
    }

    private void HandleClickWithSound(int parameter)
    {
        // Logic here.
    }
}

如果说你想要一个项目工厂概念,这里就​​是暴露的项目。

public class ItemSettableHandlers
{
    public ItemSettableHandlers()
    {
    }

    public Action LeftClickHandler { get; set; }

    public Action RightClickHandler { get; set; }

    public void HandleLeftClick()
    {
        this.LeftClickHandler?.Invoke();
    }

    public void HandleRightClick()
    {
        this.RightClickHandler?.Invoke();
    }
}

public class ItemCreator
{
    public void CreateItems()
    {
        var itemSword = new ItemSettableHandlers();
        itemSword.LeftClickHandler = () =>
        {
            // Do sword left click here.
        };
        itemSword.RightClickHandler = () =>
        {
            // Do sword right click here.
        };

        var itemShield = new ItemSettableHandlers();
        itemShield.LeftClickHandler = () =>
        {
            // Do shield left click here.
        };
        itemShield.RightClickHandler = () =>
        {
            // Do shield right click here.
        };

    }
}

推荐阅读