Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have an interface parameter, pass by reference?

I have a method with this signature:

protected bool MyMethod (ref IMyInterface model) {
    // stuff and things
}

I have a model that I'm passing in from this class:

public class MyClass: IMyInterface {
    // class stuff and things
}

I'm trying to pass my model into the method like so:

var model = new MyClass():

MyMethod(ref model);

However, I get an error about the type not matching the parameter type. If I don't pass by reference, it works fine. Or, if I cast it and pass it like so, it works fine.

var tempModel = (IMyInterface)model;

MyMethod(ref tempModel);

I'd rather avoid a cast if it's not necessary, but I can't pass without it. I thought if the class implemented the interface, I could pass the model. Is it just not a thing I can do by reference or am I missing something?

like image 797
Yatrix Avatar asked Mar 26 '15 00:03

Yatrix


1 Answers

If you don't use implicit typing, and just define your variable as the interface, it will work:

IMyInterface model = new MyClass():

MyMethod(ref model);

Arguments passed by ref must match the type exactly, as they can be reassigned within the method to another type that matches that contract. In your case, this won't work. Imagine the following:

protected bool MyMethod (ref IMyInterface model) 
{
    // This has to be allowed
    model = new SomeOtherMyInterface();
}

// Now, in your usage:
var model = new MyClass(); // Exactly the same as MyClass model = new MyClass();

MyMethod(ref model); // Won't compile...

// Here, model would be defined as `MyClass` but have been assigned to a `SomeOtherMyInterface`, hence it's invalid...
like image 74
Reed Copsey Avatar answered Sep 24 '22 02:09

Reed Copsey