Frage

Ich habe einen Streit mit einem anderen Kolleginnen und Kollegen-Programmierer, über den Umfang der Schnittstellen.

angenommen, wir haben die folgenden:

public interface IFoo
{
    string Bar { get; set; }
}

public class SomeFoo: IFoo
{
    public string Bar { get; set; }

    public SomeFoo(string bar)
    {
        this.Bar = bar;
    }
}

public class Consumer
{
    public void DoSomething()
    {
        SomeFoo fooClassInstance = new SomeFoo("test");
        IFoo fooInterface = (IFoo)fooClassInstance;

        // do something with fooInterface.
    }
}

Die Frage ist also:1.Ist es möglich, die fooClassInstance to go out of scope, bevor Sie etwas anderes Versionen der fooInterface Instanz?

Einige argumentieren, dass das Objekt (fooClassInstance) können Sie den Gültigkeitsbereich verlässt.

Ich glaube, es kann nicht.Sicher, Objekte möglicherweise nicht entsorgt, indem Sie den GC, wenn der GC entscheidet, dass das Objekt(en) sind nicht mehr im Rahmen.Da jedoch die Schnittstellen von design abstrakte Vertrages, dessen Mitglieder bereits umgesetzt werden, indem das Objekt, das es verwendet, als ein interface nicht verlieren seine Umsetzung so lange, wie das interface genutzt wird.Es ist nicht wie ein ganz anderes Objekt erstellt wird, der Typ "interface".Die Schnittstelle ist lediglich ein Zeiger auf diese abstrakten Mitglieder der Implementierung.

Können Sie Jungs mir helfen lösen diese Auseinandersetzung?

Vielen Dank,

<bleepzter />
War es hilfreich?

Lösung

Ähm, was meinst du mit "seine Implementierung verlieren"? Das macht keinen Sinn. Ein Typ implementiert eine Schnittstelle, sie kann eine Schnittstelle nicht "unimplementieren".

In Bezug auf Ihr Code -Beispiel beendet die Lebensdauer des zugewiesenen Objekts, sobald es keine Wurzeln mehr hat (auch bekannt als vom GC nicht mehr erreichbar). Ein Verweis darauf ist ein Verweis darauf, unabhängig vom Typ der Referenz (dh wenn der Referenztyp ein abgeleiteter oder übergeordneter Typ ist, spielt es keine Rolle).

ISomething Sample() {
    Something s1 = new Something();
    s2.DoSomething(); // Assuming s is the only reference to s, then it no longer is
                      // rooted after this expression

    Something s2 = new Something();
    ISomething is1 = s2;
    s2 = null;
    is1.DoSomething(); // The reference remains valid and the lifetime of the
                       // object created continues until we release all
                       // remaining references to it.
    return is1;
}

Andere Tipps

Während es definitiv einige Verwirrung in die Begriffe, die Sie verwenden (ich lasse jemand anderes tackle, Problem), ich denken Ich verstehe, was Sie sagen, und Sie sind im Grunde Recht.

Insbesondere, es klingt wie Sie Ihre Mitarbeiter glaubt, dass dies geschieht:

// Now there is this "SomeFoo" object somewhere in memory.
SomeFoo fooClassInstance = new SomeFoo("test");

// Now there is this "IFoo" object somewhere in memory.
IFoo fooInterface = (IFoo)fooClassInstance;

// Let's say down the road somewhere, fooClassInstance is set to null or a different
// object. Your coworker believes that the object it originally pointed to will then
// have no references to it and will thus be eligible for garbage collection?

Wenn die oben ist eine genaue Darstellung dessen, was Ihr Kollege denkt, dann Ihre Kollegin ist falsch und du hast Recht.Die fooInterface - variable enthält eine Referenz auf das gleiche Objekt fooClassInstance hatte einen Verweis auf.Sie können leicht überprüfen, dies einfach indem Sie Folgendes tun:

SomeFoo fooClassInstance = new SomeFoo("test");
IFoo fooInterface = (IFoo)fooClassInstance;
bool sameObject = ReferenceEquals(fooClassInstance, fooInterface);

Wenn ReferenceEquals zurück true, dann sind die beiden Variablen verweisen auf dasselbe Objekt im Speicher.


Wenn Sie Ihre Mitarbeiter bedarfsgerecht weiter zu überzeugen, versuchen, ihn/Sie so etwas wie dieses:

List<int> list = new List<int> { 1, 2, 3 };

// This cast is actually not needed; I'm just including it so that it mirrors
// your example code.
IList<int> ilist = (IList<int>)list;

// Now we remove an item from the List<int> object referenced by list.
list.Remove(3);

// Is it in ilist? No--they are the same List<int> object.
Console.WriteLine(ilist.Contains(3));

// How about we remove an item using ilist, now?
ilist.Remove(2);

// Is it in list? Nope--same object.
Console.WriteLine(list.Contains(2));

// And here's one last thing to note: the type of a VARIABLE is not the same
// as the type of the OBJECT it references. ilist may be typed as IList<int>,
// but it points to an object that is truly a List<int>.
Console.WriteLine(ilist.GetType());

Ich denke, Sie mischen die Grenze zwischen Instanz einer Referenz. fooClassInstance kann Gehen Sie aus dem Zielfernrohr (das heißt, es kann nicht mehr verwiesen werden), selbst wenn die Instanz des Objekts noch vorhanden ist (weil fooInterface Hält immer noch einen Hinweis darauf).

Zum Beispiel, wenn Sie Folgendes machen, fooClassInstance wird nach den Zahnspangen nicht verfügbar sein, aber FooInterface wird.

public void DoSomething()
{
    IFoo fooInterface;
    {
        SomeFoo fooClassInstance = new SomeFoo("test");
        fooInterface = (IFoo)fooClassInstance;
    } 

    // do something with fooInterface, but NOT with fooClassInstance
}

Es Geräusche Als ob Sie Recht haben, aber ich habe das Gefühl, dass wir einen Teil der Diskussion fehlen, da wir nicht wissen, was Sie mit dem Objekt tun, nachdem Sie es erstellt (und gegossen).

In Ihrem Beispiel:

    SomeFoo fooClassInstance = new SomeFoo("test");

Zu diesem Zeitpunkt haben Sie einen Verweis auf das von Fooclassinstance verwiesene Einfoo -Objekt.

    IFoo fooInterface = (IFoo)fooClassInstance;

Zu diesem Zeitpunkt haben Sie zwei Verweise auf das SOMFOO -Objekt (auf das sowohl von Fooclassinstance als auch von FooInterface verwiesen).

Also ja, je nachdem, wie Sie es verwenden, könnte Fooclassinstance aus dem Zielfernrohr gehen. Aber es gibt immer noch einen Hinweis darauf (FooInterface), so dass es nicht Müll gesammelt wird. Außerdem könnte die FooInterface -Referenz auf ein bisschen zurückgegeben werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top