C#中有创建匿名子类的语法吗?

问题描述 投票:0回答:4

我可以像 Java 一样在 C#/.net 中创建 abstract 类的实例吗?

附加信息

我想我们很多人都不明白我的意思是什么? 所以,在java中我可以创建这样的抽象类:

简单的抽象类:

/**
 * @author jitm
 * @version 0.1
 */
public abstract class TestAbstract
{
    public abstract void toDoSmth();
}

我创建抽象类实例的代码

/**
 * @author jitm
 * @version 0.1
 */
public class Main {
    public static void main(String[] args) {
        TestAbstract testAbstract = new TestAbstract() {
            @Override
            public void toDoSmth() {
                System.out.println("Call method toDoSmth");
            }
        };
    }
}

我可以在 C# 中做这样的事情吗?

c# .net abstract-class instance
4个回答
9
投票

在 Java 和 C# 中都不能创建抽象类的实例。 您始终需要创建一个继承抽象类的具体类。 Java 允许您使用匿名类而无需命名类即可完成此操作。 C# 没有给你这个选项。

(编辑以显示委托作为替代品。我无法访问此处的 VS,因此它可能无法编译,但这就是想法)

通常在 Java 中,当您使用带有单个抽象方法 (SAM) 的抽象类时,您真正想要实现的是将一些代码作为参数传递。 假设您需要使用 Collections.sort(Collection, Comparator) 根据类名对对象数组进行排序 (我知道Comparator是一个接口,但它是相同的想法) 使用匿名类来避免额外的输入,您可以编写类似的内容

   Comparator<Object> comparator = new Comparator<Object>{
        @Override
        public int compare(Object o1, Objecto2) {
            return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()));
        }//I'm not checking for null for simplicity
   } 
   Collections.sort(list, comparator)

在 C# 2.0 及更高版本中,您可以使用

Comparison<T>
委托执行几乎相同的操作。委托可以被视为一个函数对象,或者用 java 的话来说,就是一个具有单个方法的类。您甚至不需要创建一个类,而只需要创建一个使用关键字 delegate 的方法。

Comparison<Object> comparison = delegate(Object o1, Object o2)
{
    return o1.class.Name.CompareTo(o2.class.Name);        
};

list.sort(comparison);

在 C# 3.0 及更高版本中,您可以使用 lambda 和类型推断编写更少的代码:

list.sort((o1, o2) => o1.class.Name.CompareTo(o2.class.Name))

无论如何,如果您要将代码从 java 迁移到 c#,您应该阅读有关委托的内容...在许多情况下,您将使用委托而不是匿名类。在您的例子中,您使用的是 void toDoSmth() 方法。有一个名为 Action 的委托,它几乎是一样的东西,一个没有参数、没有返回的方法。


8
投票

不。不直接。你能找到的最接近的(假设你有以下类结构):

public abstract class AbstractClass
{
}

public class ChildClass : AbstractClass
{ 
}

是:

AbstractClass instance = new ChildClass();

0
投票

替代方案:Func<>

类型的 init 属性

我需要对一个使用

TcpClient
的类进行单元测试(这很难模拟)。我用的就是这个...

待测班级:

public Func<string, int, CancellationToken, Task> CheckConnectivityAsync { get; init; } =
    async (host, port, cancellationToken) =>
    {
        using var tcpClient = new TcpClient();
        // etc.
    };

在单元测试类构造函数中:

    _testSubject = new MyClass(context)
    {
        CheckConnectivityAsync = _mockCheck.Object
    };

使用正确的包名称,您可以加强属性的可访问性(而不是使用

public
)。


-4
投票

您的示例使用抽象类的匿名实现。 C# 不支持匿名实现,因此您需要创建另一个扩展它的实现。

公共抽象类 TestAbstract { }

公共类 AnotherTest : TestAbstract { }

© www.soinside.com 2019 - 2024. All rights reserved.