我有一个 Item
在C#类中,我想有两个方法。OnRightClick
和 OnLeftClick
但我希望每个项目在使用时都能做不同的事情(我在Unity上,这个类不是一个单行为)。
我听说过 virtual
方法,但据我所知,它们只能被其他继承它们的类重写。然而,我想做的是不用为每一个项目单独做一个类。我怎样才能使这2个方法有所不同呢?
我想到了使用 delegate
但它也没有按照我预期的方式工作。这有可能吗?
EDIT
(Ik下面的一行都不是什么东西,但这是我能以某种方式解释我想做的事的最好方法)
想象一下,有以下简单的类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
同样,这不是一个有效的代码,但我只是用这个来尝试和解释我想尝试做什么,并询问是否有任何解决方案存在。在最坏的情况下,如果没有,我可以直接使用虚拟,但我希望那是我最后没有选择的情况。
你可以有一个父项目类,然后不同的子项目类,从它继承的语法它
public class MyItem : MonoBehaviour {
public enum ItemType {HEALING, OFFENSIVE, CONSUMABLE, EQUIPMENT}
public ItemType itemType;
public float potency;
public MyItem(ItemType _it, float _potency) {
itemType = _it;
potency = _potency;
}
public void OnRightClick() {
switch (itemType) {
case ItemType.HEALING:
HealCharacter(character, potency);
break;
case ItemType.OFFENSIVE:
break;
// more cases
}
}
public void OnLeftClick() {
//fill in like onrightclick
}
}
你可以使用Action和Func来实现你的要求。
https:/docs.microsoft.comen-usdotnetapisystem.action-1?view=netcore-3.1。
https:/docs.microsoft.comen-usdotnetapisystem.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.
};
}
}
你可以使用EventHandler。
在你的类中,你定义:
public event EventHandler RightClick;
public void OnRightClick()
{
EventHandler handler = RightClick;
if (null != handler) handler(this, EventArgs.Empty);
}
你用这样的方式。
// Enable Event
RightClick += new EventHandler(OnRightClick);
OnRightClick();
public void OnRightClick(object s, EventArgs e)
{
}