C#:在不定义新类的情况下创建抽象类的实例
我知道这可以用Java来完成,因为我在过去已经广泛地使用了这种技术。下面将显示一个Java示例。(补充问题。这种技术叫什么?很难找到没有名字的例子。)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
现在,我的主要问题是,这也可以在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 !
}