I'm fairly new to JavaScript and TypeScript.
As far as I'm concerned, TypeScript is compiled into regular JavaScript.
Coming from C#, where objects are passed by reference (if they're not primitive types or structs). I've written some TypeScript code to test something:
interface IRunner {
run(): string;
}
class TestDI {
private readonly Runner: IRunner;
constructor(runner: IRunner) {
this.Runner = runner;
}
test(): void {
console.log('Result of runner: ' + this.Runner.run());
}
}
class FooRunner implements IRunner {
run(): string {
return 'Foo';
}
}
class BarRunner implements IRunner {
run(): string {
return 'Bar';
}
}
let runner: IRunner;
runner = new FooRunner();
const SUT: TestDI = new TestDI(runner);
// Expected output: Foo
// Actual output: Foo
console.log(runner.run());
// Expected output: Foo
// Actual output: Foo
SUT.test();
runner = new BarRunner();
// Expected output: Bar
// Actual output: Bar
console.log(runner.run());
// Expected output: Bar
// Actual output: Foo
SUT.test();
In the code above I've passed an instance of IRunner
interface into a class c-tor, then, a field of my class is populated with whatever I passed in the c-tor.
Later in the code I change the variable I passed into the c-tor, however, when I call the test
function Runner
field of my class seems to not reflect any changes done on the original variable I passed when creating an instance of my TestDI
class.
In C# the code I've written would behave as I expect it to. But here it's not.
What's going on?
In C# the code I've written would behave as I expect it to. But here it's not.
Not really... If you transform your code above into C# code and run it, you will see that it behaves exactly as your TypeScript code.
The reason is that you pass runner
to the constructor of TestDI
. What happens here... The content is simply copied for the call of the constructor and in this case that means that the address of the specified object is copied. If you now assign a new address of another object to runner
, why should this be reflected in the already done copy within your TestDI
instance? I guess you have mixed up something in your brain a little bit ;-)
Coming from C#, where objects are passed by reference (if they're not primitive types or structs). I've written some TypeScript code to test something:
Well yes, you CAN pass them as reference (by using ref
for example) but by default the address is simply copied (as explained above).
To make it easier for you: Just copy & paste and be suprised
class Program
{
static void Main(string[] args)
{
IRunner runner;
runner = new FooRunner();
TestDI SUT = new TestDI(runner);
// Expected output: Foo
// Actual output: Foo
Console.WriteLine(runner.Run());
// Expected output: Foo
// Actual output: Foo
SUT.Test();
runner = new BarRunner();
// Expected output: Bar
// Actual output: Bar
Console.WriteLine(runner.Run());
// Expected output: Bar
// Actual output: Foo
SUT.Test();
}
}
public interface IRunner
{
string Run();
}
public class TestDI
{
private readonly IRunner runner;
public TestDI(IRunner runner)
{
this.runner = runner;
}
public void Test()
{
Console.WriteLine("Result of runner: " + this.runner.Run());
}
}
public class FooRunner : IRunner
{
public string Run()
{
return "Foo";
}
}
public class BarRunner : IRunner
{
public string Run()
{
return "Bar";
}
}