2012-01-31 53 views
4

是否有可能複製這種提供抽象方法的功能,在一個枚舉中,內部枚舉常量必須覆蓋並提供功能?是否有可能在c#中模仿這個Java枚舉代碼#

public enum Logic { 
    PAY_DAY { 
     @Override 
     public void acceptPlayer(Player player) { 
      // Perform logic 
     } 
    }, 
    COLLECT_CASH { 
     @Override 
     public void acceptPlayer(Player player) { 
      // Perform logic 
     } 
    } 
    , 
    ETC_ETC { 
     @Override 
     public void acceptPlayer(Player player) { 
      // Perform logic 
     } 
    }; 

    public abstract void acceptPlayer(Player player); 
} 

如果不能:: 你能提供,我可以實現很多特殊的邏輯類似的方式的方式?

編輯::我知道C#中的枚舉實際上並不像Java中的'對象',但我希望執行類似的邏輯。

編輯::爲了澄清,我不想爲每個特定的邏輯位提供具體的類。 IE瀏覽器,創建接口acceptPlayer和創造了許多新的類不appropiate

+0

這是在C#中的枚舉** **沒有可能 - 就是這樣的不支持一個特徵。 – Oded 2012-01-31 20:37:17

+0

而不是解釋你**不需要**,告訴我們你**做什麼**實現。 – Oded 2012-01-31 20:39:18

+0

您可以創建一個'Action'工廠,將其傳遞給一個值,並且它會返回一個相關的「Action」來執行。 – 2012-01-31 20:41:08

回答

5

這裏有一個選項 - 不使用枚舉,但類似的十歲上下的東西...

public abstract class Logic 
{ 
    public static readonly Logic PayDay = new PayDayImpl(); 
    public static readonly Logic CollectCash = new CollectCashImpl(); 
    public static readonly Logic EtcEtc = new EtcEtcImpl(); 

    // Prevent other classes from subclassing 
    private Logic() {} 

    public abstract void AcceptPlayer(Player player); 

    private class PayDayImpl : Logic 
    { 
     public override void AcceptPlayer(Player player) 
     { 
      // Perform logic 
     } 
    } 

    private class CollectCashImpl : Logic 
    { 
     public override void AcceptPlayer(Player player) 
     { 
      // Perform logic 
     } 
    } 

    private class EtcEtcImpl : Logic 
    { 
     public override void AcceptPlayer(Player player) 
     { 
      // Perform logic 
     } 
    } 
} 

,你不希望爲每一個邏輯提供一個具體的類 - 但基本上你會用Java來做什麼,只是這個類對你來說會稍微隱藏一點。

下面是使用代理的不同行爲的另一種方法:

public sealed class Logic 
{ 
    public static readonly Logic PayDay = new Logic(PayDayAccept); 
    public static readonly Logic CollectCash = new Logic(CollectCashAccept); 
    public static readonly Logic EtcEtc = new Logic(player => { 
     // An alternative using lambdas... 
    }); 

    private readonly Action<Player> accept; 

    private Logic(Action<Player> accept) 
    { 
     this.accept = accept; 
    } 

    public void AcceptPlayer(Player player) 
    { 
     accept(player); 
    } 

    private static void PayDayAccept(Player player) 
    { 
     // Logic here 
    } 

    private static void CollectCashAccept(Player player) 
    { 
     // Logic here 
    } 
} 

在這兩種情況下,你仍然可以得到一組固定的值 - 但你不能對他們進行切換。你可能會有一個單獨的「真正的」枚舉,但這會有點混亂。

+0

我的確看到這是一個選項,但它仍然真的提供具體的類。也許可以由代表完成一些事情? – AlanFoster 2012-01-31 20:44:29

+0

嘿,我覺得很酷,我想到了和Jon Skeet一樣的解決方案(我甚至沒有看到他的第一個)。我是達曼。 – Aidan 2012-01-31 21:01:32

+0

@AlanFoster:Java中的枚舉解決方案是「仍然提供具體的類」 - 那麼爲什麼它在Java中可以使用,但在C#中卻不行?請注意,我在這裏提供了兩位代碼 - 第二位代碼使用委託。 – 2012-01-31 21:03:42

0

在c#中,你使用類而不是枚舉。用你想覆蓋的虛擬方法創建一個基類。

Java枚舉的每個成員都將是具有所需實現的子類。

最後,在每個枚舉成員的基類中創建一個只讀靜態字段,並使用該枚舉值的子類實例對其進行初始化。

1

如果你不想使用接口和一個類層次結構,你可以使用委託,是這樣的:

public class Player{} 

public static class Logic 
{ 
    public static readonly Action<Player> PAY_DAY = p => Console.WriteLine("Pay day : " + p.ToString()); 

    public static readonly Action<Player> COLLECT_CASH = p=> Console.WriteLine(p.ToString()); 

    public static void AcceptPlayer(this Action<Player> PlayerAction, Player ActingPlayer) 
    { 
     PlayerAction(ActingPlayer); 
    } 
} 

class MainClass 
{ 
    public static void Main (string[] args) 
    { 
     var player = new Player(); 

     Logic.PAY_DAY.AcceptPlayer(player); 
    } 
} 
+0

我可以問這是什麼名字嗎?這個player.AcceptPlayer現在是一個適合玩家的方法,當你在不同的類中聲明它時,它是如何的? – AlanFoster 2012-01-31 21:39:22

+0

這是一個擴展方法(實際上我已經編輯它,使它更像你的問題):http://msdn.microsoft.com/en-us/library/bb383977.aspx。第一個參數上的this關鍵字意味着任何Action 類型的實例都將具有與其關聯的AcceptPlayer方法。 – Aidan 2012-01-31 21:43:04

相關問題