-1

I have two projects say BusinessLogic (BL) and DataAccess (DL). Now I am passing type as parameter from controller to BL and to DL in the end. Below is the code.

Controller

public ActionResult SomeAction (SomeClassForTable table)
{
    bool result = new ServiceInBL.DoSomeStuffWithParameter(table);
}

BL

public class ServiceInBL
{
    bool DoSomeStuffWithParameter (SomeClassForTable classForTable)
    {
        MethodForCrudInDL dl = new MethodForCrudInDL();
        return dl.DoSomeStuffWithParameter(classForTable);
    }
}

DL

public class MethodForCrudInDL
{
    public bool DoSomeStuffWithParameter (SomeClassForTable classForTable)
    {
        return true;
    }
}

SomeClass

public class SomeClassForTable
{
    // type members
}

From my controller, I am calling method in BL and from BL, calling method in DL. Now I want to know that how many instances of SomeClassForTable will be created in memory through out the process? Will there be three instances (BL, DL, and the one in controller)?

DhavalR
  • 1,409
  • 3
  • 29
  • 57
  • I have mentioned controller. Just not shown in code. – DhavalR Apr 24 '18 at 12:38
  • If you don't show code, how would we know? – fredrik Apr 24 '18 at 12:39
  • 1
    @DhavalR: The problem is your question is unclear. If you want to know whether passing a parameter to a method creates a new copy of that then ask it. If you want to know how many instances of something will be created you ahve to show us all your code. For all we know you are creating seventeen instances of the object in your controller so we really can't actually say "only one". We can just say "in the code you are showing none". – Chris Apr 24 '18 at 12:41

3 Answers3

4

You haven't shown any instances being created - but passing a reference from one method to doesn't implicitly create a new instance, no. It copies the reference, not the object. It doesn't matter whether the methods are in the same assembly or not.

Objects can be created implicitly in this sort of situation, if there's a user-defined implicit conversion involved. For example:

public void Method1(string x)
{
    Method2(x);
}

public void Method2(XNamespace ns)
{
}

Here the call to Method2 uses a user-defined implicit conversion from string to XNamespace, which can create a new object. But if there's a reference conversion between the parameter type and the argument type (e.g. if they're the same type, or the method parameter type is a base class of the argument type) then the reference will simply be copied as the initial value of the parameter.

Things get more complicated if different AppDomains are involved, but I suspect you're not in that situation (fortunately).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Jon Skeet's example on passing object references by value as default. I believe this applies in this case [link](http://jonskeet.uk/csharp/parameters.html) – MuKa Apr 24 '18 at 12:40
  • @MuKa: I don't understand your comment, I'm afraid. Are you suggesting an inaccuracy here? *Objects* are never passed at all. References can be passed by value, or value type values can be passed by value, or variables can be passed by reference... – Jon Skeet Apr 24 '18 at 12:41
  • I was editing the comment and pressed [Enter] to go to the next line but it submitted the comment! Sorry! – MuKa Apr 24 '18 at 12:42
  • I don't think the conversion bit is relevant. Not sure why you added it TBH – Liam Apr 24 '18 at 12:42
  • @Liam: It's relevant to show that objects *can* be created as part of passing a value to a method, even though that isn't the case with the OP's code. – Jon Skeet Apr 24 '18 at 12:53
1

One instance of SomeClassForTable is created when the controller action is called. A reference to that class (the variable table) is then created. References point at the object they do not contain any data directly. Updates to the reference are re-directed to the underlying value.

Then when you call ServiceInBL.DoSomeStuffWithParameter(table); you pass the reference not the actual value. Any changes made in DoSomeStuffWithParameter will update the original object.

The same happens for MethodForCrudInDL. so in all your code there is only ever one instance of SomeClassForTable.

Note if you passed a value type (i.e. an int or struct). Then all calls to methods would create a new object every time. These objects would not update and would act independently. See What's the difference between passing by reference vs. passing by value?

See Jon Skeets blog on References and Values for more info

Liam
  • 27,717
  • 28
  • 128
  • 190
0

Logically just 1 instance exists, and it's passed through the stack because it's a ByRef parameter.

In reality, those layers are probably running on different machines and MarshalByRef might be in use to make 'all 3' pretend to be the same object... but that's copper and silicon, back in the code, you have just 1 instance.

Davesoft
  • 724
  • 1
  • 4
  • 10