【发布时间】:2016-10-21 19:46:25
【问题描述】:
这是一个非常具体的问题。甚至不知道该怎么说。基本上我正在实现工作单元和存储库模式,我有一个动态对象,我将其转换为 int,但如果我使用var,它会在尝试调用该方法时抛出异常。
我试图尽可能地删除这个问题的所有琐碎变量。出于某种原因,我只看到这两种设计模式会发生这种情况。我得到的例外是Additional information: 'BlackMagic.ITacoRepo' does not contain a definition for 'DoStuff'
代码如下:
class BlackMagic
{
static void Main(string[] args)
{
dynamic obj = new ExpandoObject();
obj.I = 69;
UnitOfWork uow = new UnitOfWork();
int i1 = Convert.ToInt32(obj.I);
var i2 = Convert.ToInt32(obj.I);
if(i1.Equals(i2))
{
uow.TacoRepo.DoStuff(i1); // Works fine
uow.TacoRepo.DoStuff(i2); // Throws Exception
}
}
}
class UnitOfWork
{
public ITacoRepo TacoRepo { get; set; }
public UnitOfWork()
{
TacoRepo = new TacoRepo();
}
}
class Repo<T> : IRepo<T> where T : class
{
public void DoStuff(int i)
{
}
}
interface IRepo<T> where T : class
{
void DoStuff(int i);
}
class TacoRepo : Repo<Taco>, ITacoRepo
{
}
interface ITacoRepo : IRepo<Taco>
{
}
class Taco
{
}
编辑: 我试图找到答案的主要问题是,为什么在工作单元内调用DoStuff 会引发异常(在使用 repo 时)但没有得到如果 BlackMagic 类中存在 DoStuff 则抛出。
【问题讨论】:
-
你能不能在调用
DoStuff之前插入一个断点,看看i2的实际运行时类型是什么? -
发生这种情况是因为运行时使用反射来尝试确定
i2的类型。但是,由于i2来自ExpandoObject,它的声明和反射类型为空,因此它不符合DoStuff的int要求。确实很奇怪,也许你应该避免以这种方式在这里使用动态。 -
@EdPlunkett 是的,这真的很奇怪,因为我以许多不同的方式测试了这个问题。但它似乎只发生在我使用工作单元和存储库模式时。我无法以任何其他方式复制它。
-
虽然我不确定原因,但我至少可以告诉你,运行时绑定器是类型确定中的谁。
-
@TravisJ 我同意 Ed 的观点。您对动态对象转换提出了一个很好的观点,但是如果我将
DoStuff从回购中取出并将其放入主“BlackMagic”类然后将 i2 传入,则不会引发错误
标签: c# repository-pattern unit-of-work expandoobject dynamicobject