简体   繁体   中英

How to get filled interface instance as a parameter of a method after executing the method?

I have a method that fills an instance of an interface as bellow:

private static void Caller() {
    IOrder order = null;

    MakeOrder(order);

    //order is empty
}

private static void MakeOrder(IOrder order) {
    order = new Order
    {
        PeriodCount = mciOrderInfo.PeriodCount,
        Quantity = mciOrderInfo.Quantity,
        ShoppingItemId = shoppingItem
    };
}

After executing this method MakeOrder the Caller will get order = null but this method fills order as above.

I know if the type of parameter was a class Order instead of interface IOrder , it will be filled and accessible in Caller method.

What is the problem?

The simpelst way is to use return :

private static void Caller()
{
    IOrder order = MakeOrder();
}

private static IOrder MakeOrder()
{
    return new Order
    {
        PeriodCount = mciOrderInfo.PeriodCount,
        Quantity = mciOrderInfo.Quantity,
        ShoppingItemId = shoppingItem
    };
}

Or, if for some reason you want to do otherwise, you can use ref / out :

private static void Caller()
{
    IOrder order;

    MakeOrder(out order);
}

private static void MakeOrder(out IOrder order)
{
    order = new Order
    {
        PeriodCount = mciOrderInfo.PeriodCount,
        Quantity = mciOrderInfo.Quantity,
        ShoppingItemId = shoppingItem
    };
}

ref passes the parameter by reference , which means if you modify it inside your function the caller's variable will be modified.

out is basically the same, except the caller doesn't have to initialize the variable, it's always the responsibility of the callee.

Yet another way would be to pass an instance and fill its properties:

private static void Caller()
{
    IOrder order = new Order();
    MakeOrder(order);
}

private static void MakeOrder(IOrder order)
{
    order.PeriodCount = mciOrderInfo.PeriodCount;
    order.Quantity = mciOrderInfo.Quantity;
    order.ShoppingItemId = shoppingItem;
}

This works because classes (and interfaces for that matter) are reference types .

You should read this MSDN article: Passing Reference-Type Parameters .

The problem is that you're dealing with multiple variables here.

This line:

MakeOrder(order);

calls MakeOrder with a copy of the value of that variable, which currently is null . Inside MakeOrder you change the local parameter variable to a new value, but the original order variable on the outside is still null .

Perhaps you want to use a return type instead:

private static void Caller()
{
    IOrder order = MakeOrder(order);
}

private static IOrder MakeOrder()
{
    return new Order
    {
        PeriodCount = mciOrderInfo.PeriodCount,
        Quantity = mciOrderInfo.Quantity,
        ShoppingItemId = shoppingItem
    };
}

Also note that the type of the parameter has nothing to with this, even if you changed MakeOrder to take a parameter of type Order (a class) you would still have the same problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM