Frage

Könnten Sie bitte erklären, was die praktische Nutzung ist für die internal Schlüsselwort in C#?

Ich weiß, dass die internal modifier beschränkt den Zugriff auf die aktuelle assembly, aber Wann und in welcher Umstand sollte ich es nutzen?

War es hilfreich?

Lösung

Utility oder Helfer-Klassen/Methoden, die Sie nutzen möchten aus vielen anderen Klassen innerhalb derselben assembly, aber dass Sie sicherstellen möchten, dass code in anderen Assemblys können nicht darauf zugreifen.

Von MSDN (via archive.org):

Eine gemeinsame Nutzung von interner Zugang ist in der Komponenten-basierten Entwicklung, denn es ermöglicht eine Gruppe von Komponenten, die zusammenarbeiten, ein Privatleben zu führen, ohne den Kontakt mit dem rest der Anwendung code.Zum Beispiel, ein framework für den Bau grafischer Benutzeroberflächen bieten könnte, die Kontrolle und Form-Klassen, die Zusammenarbeit mit den Mitgliedern mit den internen Zugriff.Da diese Mitglieder sind intern, werden Sie nicht ausgesetzt code, der mit dem Rahmen.

Sie können auch den internen Modifikator zusammen mit der InternalsVisibleTo Montage-Ebene Attribut erstellen "Freund" - Versammlungen, die gewährt werden, ein spezieller Zugang zu den Ziel-Montage interne Klassen.

Dies kann nützlich sein für die Erstellung von unit-Test-Assemblys, die sind dann erlaubt, rufen Sie die internen Mitglieder der Montage getestet werden.Natürlich keine andere Baugruppen gewährt diesen Zugang, so dass, wenn Sie release Ihre system, Kapselung beibehalten wird.

Andere Tipps

Wenn Bob Bedürfnisse BigImportantClass dann Bob braucht, um die Menschen, die eigenen Projekt zu unterzeichnen, zu garantieren, dass BigImportantClass geschrieben werden, seine Bedürfnisse zu erfüllen, getestet, um sicherzustellen, dass es erfüllt seine Bedürfnisse dokumentiert ist, wie das Zusammentreffen mit seinen Bedürfnissen, und das wird ein Prozess in Kraft gesetzt, um sicherzustellen, dass es nie so geändert wird, dass nicht mehr erfüllen seine Bedürfnisse.

Wenn eine Klasse intern ist, dann es nicht haben zu gehen durch den Prozess, spart das budget für das Projekt Ein, die Sie ausgeben können, auf andere Dinge.

Der Punkt, der innere ist nicht so, dass es macht das Leben schwierig für Bob.Es ist, dass es können Sie Steuern, was teuer, verspricht das Projekt Eine macht über die Funktionen, Lebensdauer, Kompatibilität und so auf.

Ein weiterer Grund für die Verwendung von internen ist, wenn Sie verschleiern Ihre Binärdateien.Der obfuscator weiß, dass es sicher ist, zu klettern, den Namen der Klasse von inneren Klassen, während der name des öffentlichen Klassen können nicht verschlüsselt, weil die brechen die vorhandenen Referenzen.

Wenn Sie sind schreiben einer DLL kapselt eine Tonne von komplexen Funktionalitäten, die in einem einfachen öffentliche API ist, dann "intern" verwendet, auf dem die Schüler die nicht öffentlich bloßgestellt.

Verbergen der Komplexität (eine.k.ein.Verkapselung) ist das wichtigste Konzept von Qualität in der software-engineering.

Das Schlüsselwort internal stark verwendet, wenn Sie eine wrapper-über nicht verwalteten code.

Wenn Sie eine C/C++ - basierte Bibliothek, die Sie möchten DllImport Sie importieren können diese Funktionen als statische Funktionen einer Klasse, und machen Sie intern, so dass Ihre Benutzer haben nur Zugriff auf Ihren wrapper, und nicht der ursprünglichen API, so kann es nicht Durcheinander mit etwas.Die Funktionen statisch, Sie können verwenden Sie Sie überall in der Baugruppe, für die mehrere wrapper-Klassen, die Sie brauchen.

Werfen Sie einen Blick auf Mono.Kairo, es ist ein wrapper um die cairo-Bibliothek, die verwendet diesen Ansatz.

Getrieben von "verwenden Sie als strenge modifier wie Sie" ich in der Regel verwenden internen überall, wo ich zugreifen müssen, sagen, eine Methode aus einer anderen Klasse, bis ich explizit zugreifen zu können, müssen Sie es von einer anderen assembly.

Als Montage-Schnittstelle ist in der Regel schmaler als die Summe seiner Klassen, Schnittstellen, es gibt ziemlich viele Orte, die ich verwenden es.

Ich finde interne weit überstrapaziert.Sie sollten wirklich nicht aussetzen bestimmte functionailty nur auf bestimmte Klassen, damit Sie nicht an andere Verbraucher.

Das meiner Meinung nach, bricht die Oberfläche, bricht die Abstraktion.Dies ist nicht zu sagen, es sollte niemals verwendet werden, aber eine bessere Lösung ist die Umgestaltung in eine andere Klasse oder in einer anderen Weise, wenn möglich.Dies kann jedoch nicht immer möglich.

Die Gründe, die Probleme verursachen können, ist, dass ein anderer Entwickler kann berechnet werden mit den Bau einer anderen Klasse in derselben assembly, dein ist.Mit Einbauten verringert die Klarheit der Abstraktion, und können Probleme verursachen, wenn Sie missbraucht wird.Es wäre das gleiche Problem, als wenn Sie es öffentlich.Die andere Klasse, die erstellt wird, durch die anderen Entwickler ist es immer noch Verbraucher, genauso wie jede externe Klasse.Klasse Abstraktion und Kapselung nicht nur als Schutz für/von externen Klassen, sondern für alle Klassen.

Ein weiteres problem ist, dass viele Entwickler werden denken Sie verwenden müssen, um es an anderer Stelle in der Montage-und markieren Sie es als interne wie auch immer, obwohl Sie brauche es nicht an der Zeit.Ein anderer Entwickler kann dann denken, den es für die Aufnahme.In der Regel, die Sie markieren möchten privat, bis Sie ein definative müssen.

Aber einige von diese kann subjektiv, und ich sage nicht, es sollte nie verwendet werden.Nur verwenden Sie, wenn erforderlich.

Sah interessant, den anderen Tag, vielleicht in der Woche, auf ein blog, ich kann mich nicht erinnern.Im Grunde kann ich nicht nehmen Kredit für diese, aber ich dachte, es könnte haben ein paar nützliche Anwendung.

Sagen Sie, Sie wollten eine abstrakte Klasse, zu werden gesehen von andere Montage, aber Sie wollen nicht, dass jemand in der Lage sein, auf die von Ihr Erben.Verschlossen wird nicht funktionieren, weil es Abstrakt ist, für ein Grund, den anderen Klassen in der Montage von Ihr Erben.Private wird nicht funktionieren, da Sie möglicherweise möchten, deklarieren Sie eine Übergeordnete Klasse irgendwo in der anderen Baugruppe.

namespace Base.Assembly
{
  public abstract class Parent
  {
    internal abstract void SomeMethod();
  }

  //This works just fine since it's in the same assembly.
  public class ChildWithin : Parent
  {
    internal override void SomeMethod()
    {
    }
  }
}

namespace Another.Assembly
{
  //Kaboom, because you can't override an internal method
  public class ChildOutside : Parent
  {
  }

  public class Test 
  { 

    //Just fine
    private Parent _parent;

    public Test()
    {
      //Still fine
      _parent = new ChildWithin();
    }
  }
}

Wie Sie sehen können, es effektiv ermöglicht, jemanden zu benutzen, den Übergeordneten Klasse, ohne in der Lage zu Erben.

Dieses Beispiel enthält zwei Dateien:Assembly1.cs und Assembly2.cs.Die erste Datei enthält eine interne Basisklasse BaseClass.In der zweiten Datei ein Versuch zu instanziieren, BaseClass, wird ein Fehler erzeugt.

// Assembly1.cs
// compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}

// Assembly1_a.cs
// compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main()
   {  
      BaseClass myBase = new BaseClass();   // CS0122
   }
}

In diesem Beispiel verwenden Sie die gleichen Dateien, die Sie in Beispiel 1 verwendet, und ändern Sie die Zugriffsebene von BaseClass zu public.Auch ändern Sie die Zugriffsebene des Mitglieds IntM zu interne.In diesem Fall können Sie die Klasse instanziieren, aber Sie können nicht auf den internen member.

// Assembly2.cs
// compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}

// Assembly2_a.cs
// compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {      
      BaseClass myBase = new BaseClass();   // Ok.
      BaseClass.intM = 444;    // CS0117
   }
}

Quelle: http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx

Eine sehr interessante Verwendung von internen - mit internen Mitglied der Kurs wird nur auf die Baugruppe, in der es deklariert ist - ist immer ein "Freund" - Funktion zu einem gewissen Grad aus.Ein Freund Mitglied ist etwas, das sichtbar ist nur zu bestimmten anderen Versammlungen, die außerhalb der assembly, in der Ihr erklärt.C# hat keine errichtet in der Unterstützung für den Freund, aber die CLR macht.

Sie können verwenden InternalsVisibleToAttribute zu erklären, ein Freund Versammlung, und alle Verweise innerhalb der friend-assembly behandeln die internen Mitglieder Ihrer deklarieren Montage öffentlichkeit im Rahmen der friend-assembly.Ein problem dabei ist, dass alle internen Mitglieder sichtbar sind;Sie kann nicht wählen, und wählen.

Eine gute Verwendung für InternalsVisibleTo ist, setzen Sie verschiedene interne Mitglieder zu einer Einheit test assembly wodurch die Anforderungen für komplexe Reflexion arbeiten, Tips und Tricks zu test diese Mitglieder sind.Alle internen Mitglieder sichtbar zu sein ist nicht so ein problem, jedoch kann dieser Ansatz muck up Ihre Klasse Schnittstellen ziemlich stark und kann potenziell ruinieren Verkapselung in der Erklärung der Montage.

Wenn Sie haben Methoden, Klassen, etc., die zugänglich sein müssen, im Rahmen der aktuellen Montage-und nie außerhalb.

Zum Beispiel, ein DAL, haben möglicherweise ein ORM, aber die Dinge sollten nicht ausgesetzt werden, um die business-Schicht alle-Interaktion sollte getan werden, durch statische Methoden und übergeben Sie die gewünschten Parameter.

Als Faustregel gibt es zwei Arten von Mitgliedern:

  • öffentliche Fläche:sichtbar aus einer externen Baugruppe (public, protected und internal geschützt):Anrufer, die nicht vertrauenswürdig sind, also überprüfung der parameter, Methode, Dokumentation, etc.erforderlich ist.
  • private Oberfläche:nicht sichtbar von einem externen Montage (private und interne oder interne Klassen):Anrufer ist in der Regel vertrauenswürdiger, also überprüfung der parameter, Methode, Dokumentation, etc.kann weggelassen werden.

Rauschunterdrückung, die weniger Typen, die Sie aussetzen, desto einfacher ist Ihre Bibliothek.Tamper Proof / Sicherheit ist ein weiterer (obwohl der Reflexion gewinnen können, gegen Sie).

Interne Klassen ermöglichen es Ihnen, zu begrenzen die API Ihrer Versammlung.Dies hat Vorteile, wie machen Sie Ihre API einfacher zu verstehen.

Auch, wenn ein Fehler vorhanden, die in Ihrer Montage, es ist weniger von eine chance, dass das Update die Einführung eine wichtige änderung.Ohne interne Klassen, müssten Sie davon ausgehen, dass das ändern der Klasse öffentlich-Mitglieder wäre eine bedeutende änderung.Mit inneren Klassen, können Sie davon ausgehen, dass die änderung Ihrer öffentlichen Mitglieder nur bricht die interne API der Montage (und alle Assemblys, auf die in der InternalsVisibleTo-Attribut).

Ich mag die Kapselung auf der Klassenebene und auf der assembly-Ebene.Es gibt einige, die mit diesem nicht Zustimmen, aber es ist schön zu wissen, dass die Funktionalität vorhanden ist.

Ich habe ein Projekt, das verwendet LINQ-to-SQL für die Daten-back-end.Ich habe zwei wichtigsten namespaces:Biz und Daten.Die LINQ-data-model-Leben in Daten und den Vermerk "intern";die Biz-namespace enthält die öffentlichen Klassen, die wrap-around der LINQ-data-Kurse.

So gibt es Data.Client, und Biz.Client;letztere setzt alle relevanten Eigenschaften des Datenobjekts, z.B.:

private Data.Client _client;
public int Id { get { return _client.Id; } set { _client.Id = value; } }

Die Biz-Objekte haben auch einen privaten Konstruktor (so erzwingen Sie die Verwendung der factory-Methoden) und einen internen Konstruktor, der wie folgt aussieht:

internal Client(Data.Client client) {
    this._client = client;
}

, Die verwendet werden können, indem jede der business-Klassen in der Bibliothek, aber die front-end (UI) hat keine Möglichkeit, direkt auf die Daten zugreifen, Modell, sicherzustellen, dass der business-Schicht wirkt immer als Vermittler.

Dies ist das erste mal habe ich wirklich verwendet internal viel, und es beweist durchaus nützlich.

Es gibt Fälle, wenn es Sinn macht, um die Mitglieder von Klassen internal.Ein Beispiel könnte sein, wenn Sie möchten, um zu Steuern, wie die Klassen instanziiert sind;lassen Sie uns sagen, dass Sie irgendeine Art von factory zum erstellen von Instanzen der Klasse.Sie können den Konstruktor internal, so dass das Werk (die sich in der gleichen assembly) können Instanzen der Klasse erstellen, aber der code außerhalb der assembly nicht.

Jedoch, ich sehe keinen Punkt mit, die Klassen oder an die Mitglieder internal ohne spezifische Gründe, genauso wenig wie es Sinn macht, Sie zu machen public, oder private ohne bestimmte Gründe.

die einzige Sache, die ich je benutzt habe, die interne Stichwort-ist der Lizenz-code überprüfen mein Produkt ;-)

Eine Verwendung der internen Schlüsselwort, um den Zugriff auf konkrete Implementierungen von dem Benutzer der Montage.

Wenn Sie haben eine Fabrik oder eine andere zentrale Stelle für den Bau von Objekten die Benutzer der Montage müssen nur die öffentliche Schnittstelle oder eine abstrakte Basisklasse.

Auch die interne Konstruktoren erlauben es Ihnen, zu Steuern, wo und Wann eine sonst öffentliche Klasse instanziiert wird.

Wie wäre es dieses:in der Regel wird empfohlen, dass Sie setzen Sie Sie nicht ein List-Objekt, um die externen Benutzer einer Versammlung, sondern setzen eine IEnumerable.Aber es ist viel einfacher zu verwenden Sie ein List-Objekt innerhalb der Versammlung, denn Sie erhalten die array-syntax, und alle andere Liste Methoden.So, ich haben in der Regel eine interne Eigenschaft aussetzen einer Liste verwendet werden in der Baugruppe.

Kommentare sind willkommen zu diesem Ansatz.

Beachten Sie, dass jede Klasse, definiert als public wird automatisch in der intellisense, wenn jemand schaut Ihr Projekt-namespace.Von einer API-Perspektive, ist es wichtig, dass nur Benutzer Ihres Projekts der Klassen, die Sie verwenden können.Verwenden Sie die internal Schlüsselwort, Dinge zu verbergen, sollte Sie nicht sehen.

Wenn Ihr Big_Important_Class für Project A ist vorgesehen für die Nutzung außerhalb des Projekts, dann sollten Sie nicht zu markieren internal.

Jedoch, in vielen Projekten, oft müssen Sie Klassen, die sind wirklich nur für die Verwendung in einem Projekt.Für Beispiel, Sie können eine Klasse haben, die hält die Argumente für einen parametrisierten thread-Aufruf.In diesen Fällen sollten Sie markieren Sie Sie als internal wenn aus keinem anderen Grund, als um sich selbst zu schützen durch unbeabsichtigte API ändern die Straße hinunter.

Die Idee ist, dass, wenn Sie entwerfen eine Bibliothek nur die Klassen, die dazu bestimmt sind für die Verwendung von außen (durch den Kunden Ihrer Bibliothek) sollten öffentlich sein.Auf diese Weise können Sie ausblenden von Klassen,

  1. Wahrscheinlich in zukünftigen Versionen ändern (wenn Sie öffentlich würden Sie brechen client-code)
  2. Nutzlos sind an den client und kann zu Verwirrung führen
  3. Nicht sicher (so unsachgemäße Verwendung kann brechen Sie Ihre Bibliothek ziemlich schlecht)

etc.

Wenn Sie die Entwicklung von inhouse-Lösungen als mit internen Elementen ist nicht so wichtig denke ich, weil in der Regel die Kunden haben ständigen Kontakt mit Ihnen und/oder den Zugriff auf den Quellcode.Sie sind ziemlich kritisch für library-Entwickler, obwohl.

Wenn Sie Klassen oder Methoden, die nicht passen sauber in das Objekt-Orientierte Paradigma, das gefährliche Sachen zu tun, die aufgerufen werden müssen, die aus anderen Klassen und Methoden unter Ihrer Kontrolle haben und die Sie nicht wollen, lassen Sie jemand anderes verwenden.

public class DangerousClass {
    public void SafeMethod() { }
    internal void UpdateGlobalStateInSomeBizarreWay() { }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top