【发布时间】:2010-10-29 07:50:23
【问题描述】:
到目前为止,我的猜测是动态类型只是在编译期间“关闭”类型检查,并且在动态实例上调用消息时执行类似于类型转换的操作。显然还有其他事情发生。
附加的 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);
}
其中缺少一些细节,但我希望它能说明目的。
【问题讨论】:
-
请提供完整的错误信息
-
我认为为您的实际示例制定设计注意事项可能值得提出另一个问题。必须小心你如何表达它(所以它不是开放式的),但我希望有一个评论空间以外的地方来写我的回复:)
标签: c# dynamic casting generics