Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an interface as an "out" parameter in C#

How can I use an interface or abstract class as an "out" parameter in a method in another interface? Shouldn't I be able to use an interface as an out parameter in another interface, and then have it accept any class that implements that interface when I actually call the method?

I need a Transaction interface that has a method that returns a bool and populates a "Response" object, but that response object is a different derived object for every different implementation of the Transaction interface. Thanks in advance.

namespace csharpsandbox
{
class Program
{
    static void Main(string[] args)
    {
        TransactionDerived t = new TransactionDerived();
        t.Execute();
    }
}


public interface ITransaction
{
    bool Validate(out IResponse theResponse);
}

public interface IResponse { }



public class ResponseDerived : IResponse
{
    public string message { get; set; }

}

public class TransactionDerived : ITransaction
{
    public bool Validate(out IResponse theResponse) {

        theResponse = new ResponseDerived();
        theResponse.message = "My message";
        return true;
    }

    public void Execute()
    {
        ResponseDerived myResponse = new ResponseDerived();

        if (Validate(out myResponse))
            Console.WriteLine(myResponse.message);
    }
}
}
like image 683
ARW Avatar asked Sep 23 '12 14:09

ARW


Video Answer


1 Answers

Your current implementation will work as long as you cast things appropriately:

public class TransactionDerived : ITransaction
{
    public bool Validate(out IResponse theResponse)
    {    
        theResponse = new ResponseDerived();
        ((ResponseDerived)theResponse).message = "My message";

        return true;
    }

    public void Execute()
    {
        IResponse myResponse;

        if (Validate(out myResponse))
            Console.WriteLine(((ResponseDerived)myResponse).message);
    }
}

This is messy, however. You can avoid the casting by using a generic interface instead:

public interface ITransaction<T> where T : IResponse
{
    bool Validate(out T theResponse);
}

public class TransactionDerived : ITransaction<ResponseDerived>
{
    public bool Validate(out ResponseDerived theResponse)
    {    
        theResponse = new ResponseDerived();
        theResponse.message = "My message";

        return true;
    }

    public void Execute()
    {
        ResponseDerived myResponse;

        if (Validate(out myResponse))
            Console.WriteLine(myResponse.message);
    }
}
like image 196
verdesmarald Avatar answered Sep 29 '22 06:09

verdesmarald