描述
我想将某种类型的类传递给函数参数,并期望结果是该类的实例。
在 TypeScript 中,它看起来像这样:
class Node {
evaluate<T extends typeof Node>(type: T): InstanceType<T> {
throw new Error(`Unable to evaluate ${type} from ${this}`);
}
}
但我无法在 C# 中实现它。互联网上的在线转换器和教科书建议这样做:
class Node
{
public T Evaluate<T>(T type) where T : Node, new()
{
throw new Exception($"Unable to evaluate {type.Name} from {this.Name}");
}
}
但在这种情况下,编译器不会考虑type
类型并且不会找到type.Name
:
“T”不包含“Name”的定义,并且找不到接受类型“T”的第一个参数的可访问扩展方法“Name”(您是否缺少 using 指令或程序集引用?)
问题
如何在 C# 中实现所描述的功能?
此外
我的总体目标是创建一个具有继承性的抽象类,它可以重写此方法,以便在使用它时,可以将实例转换为 Node 的另一个后代的类型。
用人类的话来解释:
abstract class Node()
{
public virtual T Evaluate<T>(T type) where T : Node, new()
{
throw new Exception($"Unable to evaluate {type.Name} from {this.GetType().Name}");
}
}
class ValueNode(double value) : Node()
{
public readonly double Value = value;
public override T Evaluate<T>(T type)
{
if (type != ValueNode) throw new Exception($"Unable to evaluate {type.Name} from {this.GetType().Name}");
return this;
}
}
class IdentifierNode(string name) : Node()
{
private static readonly Dictionary<string, double> Memory = new();
public readonly string Name = name;
public override T Evaluate<T>(T type)
{
if (type != ValueNode) throw new Exception($"Unable to evaluate {type.Name} from {this.GetType().Name}");
if (!Memory.TryGetValue(this.Name, out double? value)) throw new Exception($"Identifier '{this.Name}' does not exist");
return new ValueNode(value);
}
}
class Program
{
static void Main(string[] args)
{
{ // Example 1
ValueNode value = new(3.5);
ValueNode result = value.Evaluate(ValueNode);
}
{ // Example 2
IdentifierNode identifier = new("Name");
ValueNode result = identifier.Evaluate(ValueNode);
}
}
}
如果您对我正在尝试做的事情有更好的想法,我很乐意听到。
在ts中,类型仅在编译期间可用,因此您需要在参数中传递一些内容。而在 C# 中,输入是完整的,因此该方法根本不需要参数。
运行tio