Avatar billede boomshanka Nybegynder
25. juni 2010 - 15:00 Der er 5 kommentarer og
1 løsning

Hvorfor skal jeg oprette referencer til typer brugt i andre constructors?

Hej eksperter,

Jeg har en klasse (A.cs) som kalder en af 3 constructors i en anden klasse (B.cs). De 2 øvrige constructors i B.cs er en tom constructor og en constructor som tager en parameter af typen C.cs sådan:

public class A
{
public void CallBConstructor()
{
using(B myB = new B("mystring"))
{
...
}
}
}

public class B
{
public B(){}
public B(string myString){}
public B(C myC){}
}

public class C
{
}


Alle 3 klasser ligger i hvert sit assembly. Det jeg ikke forstår er at hvis jeg i CallBConstructor kalder default constructor B() så kompilere det fint, men hvis jeg kalder B("mystring") får jeg en kopilerfejl om at jeg skal tilføje [Namespace].C som reference i A.cs. Mit spørgsmål er nu hvorfor i alverden jeg er tvunget til at tilføje en reference til en parametertype som bliver brugt i en constructor jeg slet ikke kalder!? Hvad nu hvis C.cs lå i et assembly som ikke lige var til at få fat på?
Avatar billede arne_v Ekspert
25. juni 2010 - 15:56 #1
Jeg kan genskabe problemet.

Og det er et godt spoergsmaal.

Hvis jeg skal gaette saa er forklaringen:
- C# understoetter overload
- ogsaa af constructor
- et faktisk argument til en overloaded metode kan godt matche flere forskellige overloads
- reglen siger saa at der skal vaelges den mest specifikke klasse

Eksempel:

public class B
{
  public B(C myC){}
  public B(SubC myC){}
}

public class C
{
}

public class SubC : C
{
}

og et kald:

new B(new SubC())

vil bruge den sidste.

Mit gaet er at naar du kalder en constructor med et argument, saa skal C# comoileren have fat i all constructorer med et argument for at teste hvilken af dem der matcher bedst med dit argument.

Og den test goer det noedvendigt at kigge lidt paa typerne af parametre.

Hvis nu C var en superklasse for string, saa kunne den jo matche.
Avatar billede boomshanka Nybegynder
28. juni 2010 - 13:06 #2
Tror du har ret arne_v - en kollega henviste mig til C# Language Specification sektion 7.4.1 (http://msdn.microsoft.com/en-us/library/aa691335(v=VS.71).aspx) som blandt andet har følgende at sige omkring "method invocation":

...During the run-time processing of a function member invocation (Section 7.4.3), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

- For a value parameter, the argument expression is evaluated and an implicit conversion (Section 6.1) to the corresponding parameter type is performed...


Læser man lidt mellem linjerne kunne det godt forklare hvorfor fejlen opstår, men jeg er stadig ikke helt overbevist. Ifølge specifikationen gælder det kun for value types mens jeg i mit eksempel bruger reference types.
Avatar billede arne_v Ekspert
28. juni 2010 - 15:34 #3
Det er så runtime. Dit problem er jo compile time. Så det er ikke helt det samme.
Avatar billede arne_v Ekspert
25. juli 2010 - 22:51 #4
all set?
Avatar billede boomshanka Nybegynder
02. september 2010 - 13:27 #5
Jeg må indrømme jeg ikke er kommet tættere på en egentlig forklaring af problemet. Indtil nu har folk kun kunne gætte sig til hvad der sker.

Jeg smider lidt flere kræfter efter den før jeg lukker den.
Avatar billede boomshanka Nybegynder
02. september 2010 - 14:57 #6
Så kom svaret på stackoverflow:

http://stackoverflow.com/questions/3626641/why-am-i-forced-to-reference-types-in-unused-constructors

Som du skriver skal C# kunne læse typen af C for at kunne vælge den rigtige constructor. Det er ikke noget jeg før har tænkt over, men det er da værd at overveje når man designer sine klasser.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester