2012-01-31 64 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

相关问题