C#:在不定义新类的情况下创建抽象类的实例

C#:在不定义新类的情况下创建抽象类的实例,c#,abstract-class,abstract,anonymous-class,C#,Abstract Class,Abstract,Anonymous Class,我知道这可以用Java来完成,因为我在过去已经广泛地使用了这种技术。下面将显示一个Java示例。(补充问题。这种技术叫什么?很难找到没有名字的例子。) 现在,我的主要问题是,这也可以在C#中实现吗?如果可以,如何实现?Java技术被称为“”,在C#中没有等价物。不能在C#中实现;您需要声明一个新的类类型。在C#中最接近的可能是命名的嵌套类: public class StartHere{ private class Foo : Example { public overr

我知道这可以用Java来完成,因为我在过去已经广泛地使用了这种技术。下面将显示一个Java示例。(补充问题。这种技术叫什么?很难找到没有名字的例子。)


现在,我的主要问题是,这也可以在C#中实现吗?如果可以,如何实现?

Java技术被称为“”,在C#中没有等价物。

不能在C#中实现;您需要声明一个新的类类型。在C#中最接近的可能是命名的嵌套类:

public class StartHere{
    private class Foo : Example {
        public override void  doStuff()
        {
            Console.WriteLine("did stuff");
        }
    }
   public static void Main(string[] args){
      Example x = new Foo();
      x.doStuff();
   }
}

简而言之,不,您必须将其定义为单独的子类。我认为这项功能即将推出C#4.0版


编辑:不,不会是C#4.0,我编造的

您可以通过在.NET中进行模拟来实现这一点。但是,该功能没有语言内支持,我认为它将在C#4.0中提供。有许多用于模拟的库,包括:

    • 这在C#中不受支持,如果由我决定,也不应该如此

      java中内部类的激增主要是由于缺少委托或lambda,而C#已经做到了这一点。因此,尽管这类功能目前是java中的“唯一希望”,但您通常可以使用C#中的其他机制来实现相同的目的。在这方面,Java感觉像是用一只手弹钢琴


      (无可否认,我们中的很多人都非常擅长单手操作;现在看来,我们至少要等到java 8才能实现闭包…

      使用lamba表达式和类初始值设定项,您可以通过一些努力获得相同的行为

      public class Example {
          public Action DoStuff;
          public Action<int> DoStuffWithParameter;
          public Func<int> DoStuffWithReturnValue;
      }
      
      class Program {
          static void Main(string[] args) {
              var x = new Example() {
                  DoStuff = () => {
                      Console.WriteLine("Did Stuff");
                  },
                  DoStuffWithParameter = (p) => {
                      Console.WriteLine("Did Stuff with parameter " + p);
                  },
                  DoStuffWithReturnValue = () => { return 99; }
      
      
              };
      
              x.DoStuff();
              x.DoStuffWithParameter(10);
              int value = x.DoStuffWithReturnValue();
              Console.WriteLine("Return value " + value);
              Console.ReadLine();
          }
      }
      
      公共类示例{
      公共行动计划;
      公共行动DoStuffWithParameter;
      具有返回值的公共Func dostuff;
      }
      班级计划{
      静态void Main(字符串[]参数){
      var x=新示例(){
      多斯塔夫=()=>{
      Console.WriteLine(“做过的事”);
      },
      DoStuffWithParameter=(p)=>{
      WriteLine(“使用参数“+p”进行填充);
      },
      DoStuffWithReturnValue=()=>{return 99;}
      };
      x、 DoStuff();
      x、 DoStuffWithParameter(10);
      int value=x.dostufwithreturnvalue();
      Console.WriteLine(“返回值”+值);
      Console.ReadLine();
      }
      }
      
      我刚刚意识到这个解决方案的一个问题是,如果在示例类中创建字段,lambda表达式将无法访问这些字段

      但是,没有理由不能将示例的实例传递给lambda表达式,这将使它们能够访问该示例可能持有的任何公共状态。AFAIK在功能上等同于Java匿名内部类


      另外,如果你打算否决一个答案,请帮我们一个忙,并就你不同意的原因添加一条评论:-)

      通常,在Java中使用匿名内部类解决的问题使用.Net中的委托以更干净的方式解决。您的示例过于简单,无法确定您的意图。如果您使用抽象类的目的是传递一个“行为”,请考虑只使用
      操作
      委托

      public class StartHere{
         public static void main(string[] args){
            Action doStuff = () => Console.WriteLine("Did stuff");
            executeSomething(doStuff);
         }
      
         public static void executeSomething(Action action)
         {
            action();
         }
      }
      

      虽然所有答案都很好,但大多数解决方案都建议依赖C#3.0

      因此,为了完整性起见,我将添加另一个既不使用lambdas也不使用Func类型的解决方案(当然,正如Matt Olenik在评论中提到的,可以将下面的委托概括为同样的方式)。对于那些可能仍在使用C#2.0的人,比如我。也许不是最好的解决方案,但它是有效的

      public class Example
      {
          public delegate void DoStuffDelecate();
          public DoStuffDelecate DoStuff;
          public delegate void DoStuffWithDelecate(int n);
          public DoStuffWithDelecate DoStuffWithParameter;
          public delegate int DoStuffWithReturnDelecate();
          public DoStuffWithReturnDelecate DoStuffWithReturnValue;
      }
      
      class Program
      {
          static int MethodWithReturnValue()
          {
              return 99;
          }
          static void MethodForDelecate()
          {
              Console.WriteLine("Did Stuff");
          }
          static void MethodForDelecate(int n)
          {
              Console.WriteLine("Did Stuff with parameter " + n);
          }
      
      
          static void Main(string[] args)
          {
              var x = new Example();
              x.DoStuff = MethodForDelecate;
              x.DoStuffWithParameter = MethodForDelecate;
              x.DoStuffWithReturnValue = MethodWithReturnValue;
      
              x.DoStuff();
              x.DoStuffWithParameter(10);
              int value = x.DoStuffWithReturnValue();
              Console.WriteLine("Return value " + value);
              Console.ReadLine();
          }
      }
      

      由于您的类仅代表一个操作,因此您可以在您的案例中使用委托,因为存在一个现有委托:

      public delegate void Action();
      
      这与你的课程完全相同

      匿名类的声明更为清晰:

      Action action = () => Console.WriteLine("Hello world");
      action(); // invoke
      
      您甚至可以使用闭包:

      public void Hello(string name)
      {
        Action action = () => Console.WriteLine("Hello " + name);
        action(); // will call the above lambda !
      }
      

      我不知道在C#4.0中有任何具有这些特征的东西。这是我想到的动态关键词。。。你让我很兴奋。。。我到处寻找任何官方的“内部c#4.0类”参考资料,但没有找到-(但是很多人想要它…-1表示关于lambda表达式的错误信息。他们不需要.NET 3.5,只需要C#3.0。C#3.0编译器可以针对.NET 2.0。lambda表达式只是委托的语法糖。尽管Func类型不存在于System.Core之外,但您可以轻松定义一个等效的.Core。我希望这样。)s更准确。我自己正在从事一个ASP.NET项目,我还没有找到一种方法来分别定义所使用的框架和所使用的C#编译器,所以前面的答案是我用自己的eviroment和官方文档所能想到的。值得一提的是,C#中的内部
      私有类
      将与Java的
      pri匹配vate静态类
      内部类,因此无法访问包含类的成员。@Jean Philippellet这不是真的;C#中的
      私有类
      确实可以访问包含类的成员(甚至
      私有
      成员)。它缺少的是包含类的实例。如果实例可供嵌套类使用,则嵌套类对成员具有完全访问权限。好的,感谢您的澄清;我对我的句子进行了措辞(并使用了“访问”一词)糟糕!这不是相同的行为。匿名内部类最有用的部分是能够快速扩展类,而不必定义一个全新的类型。这不是一个解决方案。与其说不能这样做,不如用X,你应该向我们展示如何用X来完成同样的事情。
      public void Hello(string name)
      {
        Action action = () => Console.WriteLine("Hello " + name);
        action(); // will call the above lambda !
      }