C# c语言中的拦截方法/属性调用#
在下面的代码中,我有一个由main方法调用的类Foo(没有接口)。属性没有支持字段或setter,而是调用私有方法。Foo不能更改,Foo的用法也不能更改为IFoo接口 -如何更改foo.FooValue的值? -在System.Reflection、System.Reflection.Emit、.NET标准库等(不安全代码等)中是否有我可以包含在单元测试中以更改返回值的内容? 我很感激如果有什么东西注定是非常“邪恶”的,但我对“邪恶”的答案感兴趣 相关问题: -也许答案是“不”,但我不相信上面的答案,因为上面的答案只是指出,你无法通过更改(不存在的)支持字段来实现这一点 -有趣。不确定这是否是我的答案,如果是,不确定如何在单元测试中使用它C# c语言中的拦截方法/属性调用#,c#,unit-testing,reflection,C#,Unit Testing,Reflection,在下面的代码中,我有一个由main方法调用的类Foo(没有接口)。属性没有支持字段或setter,而是调用私有方法。Foo不能更改,Foo的用法也不能更改为IFoo接口 -如何更改foo.FooValue的值? -在System.Reflection、System.Reflection.Emit、.NET标准库等(不安全代码等)中是否有我可以包含在单元测试中以更改返回值的内容? 我很感激如果有什么东西注定是非常“邪恶”的,但我对“邪恶”的答案感兴趣 相关问题: -也许答案是“不”,但我不相信上面
编辑:好的。我将重新编写代码,使其更易于测试。然而,出于兴趣,有没有人成功地通过黑客破解了这种情况?您可以为
Foo
创建一个可以模拟的代理:
public class FooProxy : IFoo
{
private Foo _Foo;
public FooProxy(Foo foo)
{
_Foo = foo;
}
public int FooValue
{
get {return _Foo.FooValue();
}
}
public interface IFoo
{
public int FooValue {get;}
}
然后,您可以使用DI“注入”一个
IFoo
,使您的代码更易于测试。您可以为Foo
创建一个可以模拟的代理:
public class FooProxy : IFoo
{
private Foo _Foo;
public FooProxy(Foo foo)
{
_Foo = foo;
}
public int FooValue
{
get {return _Foo.FooValue();
}
}
public interface IFoo
{
public int FooValue {get;}
}
然后,您可以使用DI“注入”一个
IFoo
,使您的代码更易于测试。您可以为Foo
创建一个可以模拟的代理:
public class FooProxy : IFoo
{
private Foo _Foo;
public FooProxy(Foo foo)
{
_Foo = foo;
}
public int FooValue
{
get {return _Foo.FooValue();
}
}
public interface IFoo
{
public int FooValue {get;}
}
然后,您可以使用DI“注入”一个
IFoo
,使您的代码更易于测试。您可以为Foo
创建一个可以模拟的代理:
public class FooProxy : IFoo
{
private Foo _Foo;
public FooProxy(Foo foo)
{
_Foo = foo;
}
public int FooValue
{
get {return _Foo.FooValue();
}
}
public interface IFoo
{
public int FooValue {get;}
}
然后您可以使用DI“注入”一个
IFoo
,使您的代码更易于测试。您拥有Foo
类吗?您将其硬编码为返回0。添加一个属性或字段,然后让它返回属性并添加一个setter。那么您的兴趣仅仅是单元测试?你实际上是想通过改变Foo的行为来“模仿”Foo
。我宁愿不重构,如果我要重构的话,我会通过使用at作为IFoo将Foo与代码分离。@DStanley基本上是的。我的三个步骤是:我可以模拟它(否),我可以反映它(否),让我们来看看实现。你想测试FooValue
的值还是依赖于FooValue
的其他东西?你拥有Foo
类吗?您将其硬编码为返回0。添加一个属性或字段,然后让它返回属性并添加一个setter。那么您的兴趣仅仅是单元测试?你实际上是想通过改变Foo的行为来“模仿”Foo
。我宁愿不重构,如果我要重构的话,我会通过使用at作为IFoo将Foo与代码分离。@DStanley基本上是的。我的三个步骤是:我可以模拟它(否),我可以反映它(否),让我们来看看实现。你想测试FooValue
的值还是依赖于FooValue
的其他东西?你拥有Foo
类吗?您将其硬编码为返回0。添加一个属性或字段,然后让它返回属性并添加一个setter。那么您的兴趣仅仅是单元测试?你实际上是想通过改变Foo的行为来“模仿”Foo
。我宁愿不重构,如果我要重构的话,我会通过使用at作为IFoo将Foo与代码分离。@DStanley基本上是的。我的三个步骤是:我可以模拟它(否),我可以反映它(否),让我们来看看实现。你想测试FooValue
的值还是依赖于FooValue
的其他东西?你拥有Foo
类吗?您将其硬编码为返回0。添加一个属性或字段,然后让它返回属性并添加一个setter。那么您的兴趣仅仅是单元测试?你实际上是想通过改变Foo的行为来“模仿”Foo
。我宁愿不重构,如果我要重构的话,我会通过使用at作为IFoo将Foo与代码分离。@DStanley基本上是的。我的三个步骤是:我可以模拟它(否),我可以反映它(否),让我们来看看实现。你想测试FooValue
的值还是取决于FooValue
的其他值?谢谢你的回答。我知道如果我的代码使用接口,它将更易于测试。一般来说,dto并不是这样(foo是一种dto,有人对它的实现有点热情)。如果我这样做了,我可能只会使用Moq而不是代理。因此,您对我的问题的回答是:“您的代码是不稳定的,在重构之外没有模仿Foo的技巧”@NathanCooper-我喜欢您旋转答案的方式:)-在.Net中没有任何轻量级的东西可以处理对非虚拟/非接口方法的拦截调用。某种形式的IL重写是可以实现这一点的最高抽象层,使用调试接口或自定义JIT/运行时是下一步…@Nathan你的程序与Foo
紧密耦合-如果你需要用Foo
以外的东西测试你的方法,正确的方法是打破紧密耦合。可能有低级的方法(IL重写等),但它们只是绕过了真正的问题。谢谢你的回答。我知道如果我的代码使用接口,它将更易于测试。一般来说,dto并不是这样(foo是一种dto,有人对它的实现有点热情)。如果我这样做了,我可能只会使用Moq而不是代理。所以你对我的问题的回答是:“你的代码是不稳定的,在重构之外没有模仿Foo的技巧”@NathanCooper-我喜欢你旋转答案的方式:)-在.Net中没有什么轻量级的东西可以用来拦截对非病毒的调用