问题描述
我想创建一个应该实现通用单元测试的类型层次结构,使用抽象类型作为测试夹具。相同的模式在 C# 中运行良好,但我面临编译器错误:“泛型构造要求类型‘IConditionalOperator’具有公共默认构造函数。”:
type Color =
| White = 0xFFFFFF
| Silver = 0xC0C0C0
| Gray = 0x808080
type IConditionalOperator =
abstract member GetName : Color -> string
type PatternMatching() =
interface IConditionalOperator with
member this.GetName color =
match color with
| Color.White -> "White"
| Color.Silver -> "Silver"
| Color.Gray -> "Gray"
| _ -> "None"
[<AbstractClass>]
type ConditionalOperatorTest<'T when 'T :> IConditionalOperator and 'T : (new : unit -> 'T)>() =
member this.ConditionalOperator_ReturnsName(name: string) = None
type PatternMatchingtest() =
inherit ConditionalOperatorTest<IConditionalOperator>()
相应的 C# 代码有效,如下所示:
public enum Color
{
White = 0xFFFFFF,Silver = 0xC0C0C0,Gray = 0x808080,}
public interface IConditionalOperator
{
string GetName(Color color);
}
public class IfStatement : IConditionalOperator
{
public string GetName(Color color)
{
if (color == Color.White)
{
return "White";
}
else if (color == Color.Silver)
{
return "Silver";
}
else if (color == Color.Gray)
{
return "Gray";
}
else
{
return "None";
}
}
}
public abstract class ConditionalOperatorTest<T> where T : IConditionalOperator,new()
{
public void ConditionalOperator_ReturnsName(Color color,string name) {}
}
public class IfStatementTest : ConditionalOperatorTest<IfStatement> {}
解决方法
您已定义 ConditionalOperatorTest<'T>
以便它要求 'T
具有默认构造函数,这意味着 'T
不能是接口。因此,不要将 IConditionalOperator
指定为 'T
,而是使用具体的 PatternMatching
类型:
type PatternMatchingTest() =
inherit ConditionalOperatorTest<PatternMatching>()
进行此更改后,F# 版本现在与原始 C# 代码匹配:ConditionalOperatorTest<IfStatement>