gpt4 book ai didi

c# - 为什么动态类型可以在类型转换不起作用的地方工作?

转载 作者:行者123 更新时间:2023-11-30 15:46:52 25 4
gpt4 key购买 nike

到目前为止,我的猜测是动态类型只是在编译期间“关闭”类型检查,并在动态实例上调用消息时执行类似于类型转换的操作。显然还有其他事情正在发生。

附加的 NUnit 测试用例显示了我的问题:使用动态类型我可以使用仅在具体子类中可用的方法,但我不能使用强制转换来做同样的事情(导致 InvalidCastException)。我宁愿进行转换,因为这使我可以在 VS 中完成完整的代码。

任何人都可以解释发生了什么和/或给我一个提示,我可以如何在我的案例中完成代码,而不必在每个具体子类中重新实现 WorkWithAndCreate 方法?

干杯,约翰内斯

using System;
using NUnit.Framework;

namespace SlidesCode.TestDataBuilder
{
[TestFixture]
public class MyTest
{
[Test]
public void DynamicWorks()
{
string aString = CreateDynamic(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}

private static string CreateDynamic(Action<dynamic> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}

[Test]
public void CastingDoesNotWorkButThrowsInvalidCastException()
{
string aString = CreateWithCast(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}

private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate((Action<MyGenericClass<string>>) action);
}
}

internal abstract class MyGenericClass<T>
{
public abstract T Create();
public T WorkWithAndCreate(Action<MyGenericClass<T>> action)
{
action(this);
return this.Create();
}
}

internal class MyConcreteClass : MyGenericClass<string>
{
public override string Create()
{
return "a string";
}

public void OnlyInConcreteClass()
{
}
}
}

这是我评论中格式化的现实世界示例:

Customer customer = ACustomer(cust =>
{
cust.With(new Id(54321));
cust.With(AnAddress(addr => addr.WithZipCode(22222)));
});

private static Address AnAddress(Action<AddressBuilder> buildingAction)
{
return new AddressBuilder().BuildFrom(buildingAction);
}

private static Customer ACustomer(Action<CustomerBuilder> buildingAction)
{
return new CustomerBuilder().BuildFrom(buildingAction);
}

它缺少一些细节,但我希望它能说明目的。

最佳答案

原因dynamic作品是dynamic不依赖于对象类型的编译时知识。 MyGenericClass<string>没有方法 OnlyInConcreteClass() ,但是您传递的实例当然有方法和 dynamic找到这个。

顺便说一句,你可以制作WorkWithAndCreate像这样工作:

public T WorkWithAndCreate<T1>(Action<T1> action)
where T1 : MyGenericClass<T>
{
action((T1)this);
return this.Create();
}

然后,调用也将起作用:

private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}

你现在不必再施放它了。

关于您的构建器,以下是否可行?

private static TResult AnInstance<TBuilder, TResult>(Action<TBuilder> buildingAction)
where TBuilder : Builder<TResult>, new()
{
return new TBuilder().BuildFrom(buildingAction);
}

关于c# - 为什么动态类型可以在类型转换不起作用的地方工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4049992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com