我可以像 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# 中做这样的事情吗?
在 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 的委托,它几乎是一样的东西,一个没有参数、没有返回的方法。
不。不直接。你能找到的最接近的(假设你有以下类结构):
public abstract class AbstractClass
{
}
public class ChildClass : AbstractClass
{
}
是:
AbstractClass instance = new ChildClass();
替代方案: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
)。
您的示例使用抽象类的匿名实现。 C# 不支持匿名实现,因此您需要创建另一个扩展它的实现。
公共抽象类 TestAbstract { }
公共类 AnotherTest : TestAbstract { }