On Thursday, April 15, 2010 3:48:55 AM UTC-7, bill richards wrote:
> I would say that just because code has been written and tested does
> not make it a good design.
> 
> In C++ I can do the following ...
> 
> public class Triangle { }
> public class Square { }
> public class Shape : Triangle, Square { }
> 
> it will compile, I will be able to test it, but it really is not good
> design
> 
> In C# I can do this ....
> 
> // in assembly A
> namespace A {
> public class ClassA {
>   private ClassB _classB;
>   public ClassA(ClassB b) { _classB = b; }
> }
> 
> // in assembly B
> namespace B {
> public class ClassB {
>   private ClassC _classC;
>   public ClassA(ClassC c) { _classC = c; }
> }
> 
> // in assembly C
> namespace C {
> public class ClassC {
>   private ClassA _classA;
>   public ClassA(ClassA a) { _classA = a; }
> }
> 
> This does not necessarilymake a good design.
> 
> On Apr 14, 8:52 pm, BaRuSa <[email protected]> wrote:
> > >> public class MyImpl : AbstractExample
> > >> {
> > >>    public MyImpl(string s) : base(s) { }
> > >>    public MyImpl(IExampleInterface iei) : base(iei) { }
> > >>}
> >
> > The MyImpl class works perfectly fine in the .NET framework because at
> > compile time 's' is a string and 'iei' is an IExampleInterface
> > regardless of what data they hold (or don't hold).  Thus the following
> > overly simple code compiles and runs.
> >
> > MyImpl first = new MyImpl("TEST");
> > MyImpl second = new MyImpl(first);
> >
> > Correct,
> >
> > var instance = MyImpl(null);
> >
> > is a compile time error.  This is a completely acceptable result for
> > so many reasons I won't even count them.
> >
> > // The birth of a string some where in code
> > string externalString = GetStringFromExternalSource();
> > // Do Stuff
> > var instance = MyImpl(externalString);
> >
> > The developer of AbstractExample has no control of
> > GetStringFromExternalSource or what happens to externalString before
> > it enters AbstractExample.  If externalString is null, there is no
> > compile time error because the compiler knows which constructor to
> > call.  Neither the compile time nor run time knows that having
> > externalString as null is bad.  Only the implementer of
> > AbstractExample knows that receiving null is bad.  Thus it is the
> > obligation of the AbstractExample developer to inform the user of
> > AbstractExample that null is bad, which is frequently done through the
> > use of an exception.
> >
> > >> My advice would be to think more carefully about what it is that yor
> > >> object is suppoed to be doing.
> >
> > This is what the objects are supposed to be doing.
> >
> > A.)  Have a common interface to support polymorphic features.  (using
> > interface)
> >
> > B.)  Have a base class to support shared functionality that interact
> > with immutable fields.  (using abstract class)
> >
> > C.)  Have different class types that have different data types. (this
> > part is working)
> >
> > D.)  Set immutable data in the base class at the time of
> > construction.  (The data happens to be a reference object that accepts
> > null.)
> >
> > E.)  Copy immutable data in the base class from another similar object
> > at the time of construction.  (That object also happens to be a
> > reference object that accepts null.)
> >
> > That code has been written.  Everthing works and is tested except we
> > haven't found a good way to test D. and E. receiving null.
> >
> > On Apr 14, 11:38 am, bill richards <[email protected]>
> > wrote:
> >
> >
> >
> > > My answer to this is that you have a flawed design in AbstractExample.
> >
> > > Firstly, if you had developed this in a TDD fashion, you would not end
> > > up with an object that takes two types as alternate constructors.
> >
> > > My advice would be to think more carefully about what it is that yor
> > > object is suppoed to be doing. Quite frankly, even the .net framework
> > > would be confused
> >
> > > public class MyImpl : AbstractExample
> > > {
> > >     public MyImpl(string s) : base(s) { }
> > >     public MyImpl(IExampleInterface iei) : base(iei) { }
> >
> > > }
> >
> > > var instance = MyImpl(null);   ... what constructor should be invoked?
> >
> > > On Apr 14, 3:34 pm, BaRuSa <[email protected]> wrote:
> >
> > > > Simplified example of a class:
> >
> > > > abstract class AbstractExample : IExampleInterface
> > > > {
> > > >   protected AbstractExample(string name) { /* Do Stuff */ }
> > > >   protected AbstractExample(IExampleInterface deepCopy) { /* Do Stuff
> > > > */ }
> > > >   // abstract methods
> >
> > > > }
> >
> > > > Simpiflied test for constructor:
> >
> > > > [ExpectedException(typeof(ArgumentNullException))]
> > > > void Test()
> > > > {
> > > >   AbstractExample example;
> > > >   string name;
> >
> > > >   name = null;
> > > >   example = MockRepository.GenerateStrictMock<AbstractExample>(name);
> >
> > > > }
> >
> > > > The test creates an exception
> > > > "System.Reflection.AmbiguousMatchException: Ambiguous match found."  I
> > > > am assuming the problem is there are two constructors that could
> > > > accept null, but Rhino Mocks doesn't know which type to use.  I know
> > > > there are constraints that be placed on methods; are there constraints
> > > > for calling constructors?  Is there a different solution I am not
> > > > thinking about?- Hide quoted text -
> >
> > > - Show quoted text -- Hide quoted text -
> >
> > - Show quoted text -

I am sure that this is not a bad design of the thread starter.
I've hit the same issue while mocking WPF Prism API. There are overloaded 
methods that I want to mock, and Rhino have no clue which one to call. Can give 
you one more example where it is going to fail: say, you are implementing a 
Visitor pattern in such a strongly typed language as C#, and you want the 
methods on the Visitor to be overloaded for different types of Visitables. You 
create some Visitable and want to check if it invokes the right method on the 
mocked Visitor. And with Rhino you see how it miserably fails.

Whoever is going to fix the issue, should change the mechanism that is being 
used to the compiled expression. If it compiles, it shall never fail then.

-- 
You received this message because you are subscribed to the Google Groups 
"Rhino.Mocks" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rhinomocks.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to