Verständnisfrage zu internal


  • Administrator

    Hallo zusammen,

    Ich möchte, dass eine Klasse nur von einer anderen Klasse erstellt werden kann. friend gibt es ja nicht, aber dafür internal . internal sagt ja aus, dass nur Klassen aus der gleichen Assembly darauf zugreifen können, oder? Also wenn ich eine DLL schreibe und dann sowas mache:

    // Foo.cs
    
    namespace FooBarLib
    {
      public class Foo
      {
        public string Name { get; internal set; }
    
        internal Foo(string name)
        {
          this.Name = name;
        }
      }
    }
    
    // Bar.cs
    
    namespace FooBarLib
    {
      public class Bar
      {
        public Foo createFoo(string name)
        {
          return new Foo(name);
        }
      }
    }
    

    Somit ist Foo nur durch meine Klassen in der DLL erstellbar, wie zum Beispiel durch Bar ? Und die Eigenschaft Name kann nur durch Klassen in der DLL geändert werden und nicht von jemanden, welcher die DLL benutzt? Also durch keine Klasse ausserhalb der DLL?

    Gibt es noch eine strengere Bindung für sowas als internal ?

    Grüssli





  • Somit ist Foo nur durch meine Klassen in der DLL erstellbar, wie zum Beispiel durch Bar? Und die Eigenschaft Name kann nur durch Klassen in der DLL geändert werden und nicht von jemanden, welcher die DLL benutzt? Also durch keine Klasse ausserhalb der DLL?

    Genau. internal ist innerhalb der Assembly wie public , nach aussen hin aber wie private .

    Gibt es noch eine strengere Bindung für sowas als internal?

    In C# nicht. Die CLR kennt noch zwei weitere Unterscheidungen der Sichtbarkeit ( privatescope und familyandassem ), aber die nützen dir auch nichts.


  • Administrator

    theta schrieb:

    http://msdn.microsoft.com/en-us/library/7c5ka91b.aspx

    Ja, habe ich schon durchgelesen, war aber trotzdem noch verunsichert. Es ist irgendwie etwas seltsames dieses internal . Hab noch nie was vergleichbares gesehen, deswegen bin ich ein wenig verwirrt 😉

    @/rant/,
    Ok, danke!

    Grüssli



  • Dravere schrieb:

    Es ist irgendwie etwas seltsames dieses internal . Hab noch nie was vergleichbares gesehen, deswegen bin ich ein wenig verwirrt 😉

    Dann hast du dich vermutlich noch nie mit Java beschäftigt.
    Und was ist daran seltsam?

    Kommt doch andauernd vor, dass Klassen eng zusammenarbeiten müssen. Und dass Klasse X.A daher Zugriff auf gewisse Dinge in Klasse X.B braucht, man diesen Zugriff aber nicht allen Klassen in allen Programmen erlauben will. In C++ verwendet man dafür "friend" (muss man anders anwenden, erfüllt aber den gleichen Zweck).

    Die einzig andere Möglichkeit sowas in C# zu machen wäre "nested classes" zu verwenden. Oft "passt" es aber überhaupt nicht, eine Klasse zur "nested class" einer anderen zu machen, wenn beide eng zusammenarbeiten müssen. Von daher ist es gut dass es "internal" gibt. Ich verwende das recht oft.


  • Administrator

    hustbaer schrieb:

    Dann hast du dich vermutlich noch nie mit Java beschäftigt.

    Doch, aber sowas wie das internal in C# gibt es dort nicht. Man kann nur im aktuellen File etwas bekannt geben, also jeweils pro public class. Über das ganze Projekt geht nicht, bzw. das ist ja sowieso ein Problem von java, dass man am Ende hunderte von *.class Files hat. Und nur einen *.jar etwas freigegeben, davon wäre mir in Java nichts bekannt.

    hustbaer schrieb:

    Und was ist daran seltsam?

    Frage mich was besseres 😃
    Es ist irgendwie seltsam, dass man etwas einer Assembly freigeben kann. Ich gehe bereits in C++ sehr vorsichtig mit friend um und jetzt plötzlich in C#, wo man es nur der ganzen Assembly freigeben kann oder nicht, ka ... fühlt sich ungeschützt an 🙂
    Auf der anderen Seite sehe ich durchaus den Nutzen darin und auch die Vereinfachung dadurch. Gerade auch um eine Bibliothek in einer DLL zu schreiben, es kommt einem so seltsam einfach vor... Völlig ungewohnt, daran kommt nicht mal Java ran 😉

    Ich muss mich halt einfach noch an C# gewöhnen. Deshalb schreibe ich ja nun auch meine 2. Anwendung darin. Diesmal ein wenig grösser, mit einer DLL und mit WPF.

    Grüssli



  • Java hat "default" ("friendly"), was auf "package" (namespace) Ebene arbeitet, statt auf "assembly" Ebene. Also schon etwas mehr als nur ein File.

    Gerade auch um eine Bibliothek in einer DLL zu schreiben, es kommt einem so seltsam einfach vor...

    Ja genau dafür ist "internal" ja da. Für Exen ist es eher weniger interessant. Obwohl man dadurch natürlich auch z.B. bei Plugin-Architekturen den Plugins einige Möglichkeiten nehmen kann - also indem man "internal" statt "public" verwendet.

    Persönlich mag ich "friend" lieber, aber "internal" ist IMO "the next best thing".


  • Administrator

    hustbaer schrieb:

    Java hat "default" ("friendly"), was auf "package" (namespace) Ebene arbeitet, statt auf "assembly" Ebene. Also schon etwas mehr als nur ein File.

    War es auf das ganze package ? Hmmm, ist inzwischen bald ein Jahr her, seit ich das letzte Mal mit Java programmiert habe 🙂

    hustbaer schrieb:

    Persönlich mag ich "friend" lieber, aber "internal" ist IMO "the next best thing".

    "The next best thing" + " defined by Microsoft"? 🙂

    Grüssli



  • Dravere schrieb:

    Es ist irgendwie seltsam, dass man etwas einer Assembly freigeben kann. Ich gehe bereits in C++ sehr vorsichtig mit friend um und jetzt plötzlich in C#, wo man es nur der ganzen Assembly freigeben kann oder nicht, ka ... fühlt sich ungeschützt an 🙂

    Dann zerteile halt Deine Logok in mehrere Assemblys, ist ja nicht so dass Du für jedes extra Assembly 10 Euro zahlen mußt oder so.


  • Administrator

    witte schrieb:

    Dann zerteile halt Deine Logok in mehrere Assemblys, ist ja nicht so dass Du für jedes extra Assembly 10 Euro zahlen mußt oder so.

    LoL, so dass am Ende für jede Assembly zwei Klassen existieren? Für die DLL, wo ich internal benutze, existiert ja sowieso erst ein einziger Namespace. Viel mehr als 10 - 15 Klassen wird es wohl nicht geben und die grössere Menge werden wohl EventArgs Klassen sein, wobei das noch nicht alles in Stein gemeisselt ist 😉

    Allerdings merke ich mehr und mehr die Vorteile von C#. Wie gesagt, es ist halt ein Angewöhnungsprozess.
    Gerade in dieser DLL werden ständig Dinge mit einem Server abgeglichen. Die meistens Änderungen kann der User nur verzögert machen, also erst die Bestätigung des Server verändert die Daten. So kann ich die entsprechenden Setter Funktionen internal machen, die Getter public und die Events auf die Wesentlichen beschränken. Eigentlich ganz praktisch 🙂

    Grüssli


Anmelden zum Antworten