Utwórz obiekt, którego stan zmienia się przy przypisaniu

31

Uważam za głęboko dziwne, że jest to możliwe w Ruby (nie od razu powiem jak):

obj = #code redacted

print obj.state # Some value.

LValue = obj

print obj.state # Different value!

Twoim wyzwaniem jest stworzenie kodu z grubsza z tej formy. Utwórz obiekt i przypisz go do zmiennej. Powinien mieć określony atrybut (lub deterministyczną, idempotentną metodę), jak statewyżej, który zmienia się po przypisaniu obiektu do nowego identyfikatora ( LValuepowyżej), nawet jeśli nadal używasz starego identyfikatora ( objpowyżej), aby się do niego odwoływać.

Edytuj dla wyróżnienia : statelub odpowiednik musi być idempotentny, więc utworzenie akcesora, który modyfikuje wartość, lub z jakiegokolwiek innego powodu zwraca różne wyniki, gdy jest wywoływany kilka razy z rzędu, nie jest prawidłowym rozwiązaniem. Lub, mówiąc prościej, musi to być zadanie, które zmienia stan.

Każdy język z przypisaniem jest kwalifikowalny, chociaż prawdopodobnie istnieją takie, w których nie ma w pełni uzasadnionego rozwiązania. Opublikuję moją odpowiedź Ruby, jeśli nikt inny nie dostanie jej po kilku dniach, i będę przyjmować odpowiedzi o najwyższym głosowaniu na bieżąco.

histocrat
źródło
Czy LValue = objlinia musi być wymagana statedo faktycznej zmiany? (Mógłbym po prostu stworzyć właściwość w języku C #, która zwiększa się za każdym razem, gdy ją zdobędziesz)
Tim S.
2
Tak, właśnie to zamierzałem, mówiąc, że metoda musi być idempotentna. Będę edytować, aby to wyjaśnić.
histocrat
Ok dzięki. Musiałem przeoczyć tę część.
Tim S.
4
Czy po prostu zwróci przeliczenie obiektu?
Nick T
Czy destrukcyjne zmiany w samym obiekcie? EmacsLisp: (setq a (list "val")) (setq b (nconc a "val2"))na przykład. akończy się tak jak ("val" . "val2")w tym momencie.
Jonathan Leech-Pepin

Odpowiedzi:

30

C ++

Jest to banalne przy użyciu odpowiednich narzędzi.

#include <iostream>

using namespace std;

class Obj {
public:
   int state;

   Obj& operator= (Obj& foo) {
      foo.state++;
      this->state = foo.state - 2;
      return *this;
   }
};

int main() {
   Obj a, b, c, d;
   a.state = 3;
   b.state = 4;

   cout << a.state << " " << b.state << "\n";

   c = a;
   d = b;

   cout << a.state << " " << b.state << " " << c.state << " " << d.state << "\n";

   return 0;
}

Wydajność:

3 4
4 5 2 3
marinus
źródło
12
W momencie, gdy zobaczyłem tytuł, wiedziałem, że ktoś spowoduje przeciążenie operatora. To oczywisty sposób. Zyskaj głos.
17

PHP (kompilacja debugowania,> = 5,4)

Używamy przeliczania obiektu w getterze. (Tak więc, zgodnie z przypisaniem, wzrost kont i zmiany wartości)

class State {
    public function __get($arg) {
        ob_start();
        debug_zval_dump($this); // e.g. "object(State)#1 (0) refcount(6)"
        return ob_get_clean()[29];
    }
}

$obj = new State;
var_dump($obj->state);
$a = $obj;
var_dump($obj->state);
Bwoebi
źródło
14

DO#

Dwie proste opcje:

class Obj
{
    public int state;
    public static implicit operator int(Obj o)
    {
        return o.state++;
    }
}

static int LValueI;
static Obj LValueM { set { value.state++; } }
static void Main()
{
    var obj = new Obj { state = 1 };
    LValueI = obj;
    Console.WriteLine(obj.state); //2, caused by the implicit cast.

    LValueM = obj;
    Console.WriteLine(obj.state); //3, caused by the property setter.
    Console.ReadLine();
}

Lub możemy po prostu napisać w tej samej pamięci:

[StructLayoutAttribute(LayoutKind.Explicit)]
class Program
{
    [FieldOffset(0)]
    int state = 1;
    [FieldOffset(1)]
    int LValue;

    void Test()
    {
        var obj = this;

        Console.WriteLine(state);  //1
        LValue = state;
        Console.WriteLine(state);  //257
        Console.ReadLine();
    }
    static void Main() { new Program().Test(); }
}
NPSF3000
źródło
12

TeX, znacznie krótszy niż inne odpowiedzi tutaj

\setbox0=\hbox{Hello world!} % Put stuff in the box 0.
\message{\the\wd0}           % Print the width of the box => non-zero
\setbox2=\box0               % Put the box instead in box 2.
\message{\the\wd0}           % Now box 0 is void, hence has zero width.

Jako system składu, TeX ma typ „box”, który zawiera materiał składu. Ponieważ najczęstszym przypadkiem użycia jest przenoszenie tego materiału, dzielenie go itp., Zamiast tworzenia kopii, ramki są zwykle usuwane po użyciu (lub raczej zmienne „box” są wskaźnikami i tylko jeden wskaźnik na raz może wskazywać do rzeczywistej skrzynki w pamięci). Nie potrzeba żadnej magii.

Bruno Le Floch
źródło
8

C ++ 11 (Więc zapomnieliście o Unique_ptr / shared_ptr :-))

#include <iostream>
#include <memory>
using namespace std;
int main() {
    std::unique_ptr<int> u1(new int(0)), u2;
    std::shared_ptr<int> s1 = std::make_shared<int>(0), s2;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
    u2 = std::move(u1);
    s2 = s1;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
   return 0;
}
Abhijit
źródło
7

Fortran 03

Jest to nieco podobne do odpowiedzi Hugo D, ale jest nieco bardziej ukryte (częściowo dlatego, że kto # $% ^ zna Objectran zorientowany Fortran)?

module objects
   implicit none

   type ObjDef
      integer :: state
    contains
      procedure :: initObject
      procedure :: printObject
      procedure :: setNew
   end type
 contains
   subroutine initObject(this)
     class(ObjDef) :: this
     this%state = this%state + 1
   end subroutine initObject

   subroutine printObject(this)
     class(ObjDef) :: this
     print '(a,i0)',"this%state = ",this%state
   end subroutine printObject

   subroutine setNew(this,that)
     class(ObjDef) :: this,that
     that%state = this%state
   end subroutine setNew

end module objects

program objectChange
   use objects
   type(ObjDef) :: a,b

   call initObject(a)
   call printObject(a)
   call b%setNew(a)
   call printObject(a)
end program objectChange

Dane wyjściowe to

this%state = 1
this%state = 0

Jeśli możesz dowiedzieć się, co się stało, zdobądź punkty bonusowe! Jeśli nie:

Przy wywołaniu procedury setNeww formie call b%setNew(a), bjest niejawnie pierwszy argument, a nie drugi.

Kyle Kanos
źródło
7

PowerShell

Spowoduje to utworzenie obiektu, którego statewłaściwością są nazwy zmiennych wskazujących na obiekt.

$a = @{}| Add-Member -MemberType:16 -PassThru state -Value {
        (gv|?{$this -eq $_.Value}|%{$_.Name}) -join ','} 

'Before: ' + $a.state
$b = $a
'After: ' + $a.state

Wydajność

Before: a,this
After: a,b,this

Uwaga: To nie działa, jeśli przypisanie odbywa się w zasięgu potomnym.

'Before: ' + $a.state
&{$b = $a}
'After: ' + $a.state

Wyjścia

Before: a,this
After: a,this
Rynant
źródło
Get-Variable jest inteligentny!
mazzy
5

Perl 5

Oto jeden ze sposobów, aby to zrobić w Perlu:

package Magic {
    sub new { bless {state => 1} }
    use overload '""' => sub { $_[0]{state}++ };
}
use feature 'say';

my $obj = new Magic;
say $obj->{state};
substr($_, 0) = $obj;
say $obj->{state};

To daje:

1
2

Wyjaśnienie:

Jest to proste zastosowanie przeciążenia . W szczególności przeciążam operator konwersji ciągów "", który jest wywoływany, gdy przypisany jest przeciążony obiekt substr()(co, tak, jest to prawna wartość w Perlu).

Istnieje również wiele specjalnych zmiennych w Perlu, które określają wszystko, co jest do nich przypisane. Na przykład działa również:

my $obj = new Magic;
say $obj->{state};
$0 = $obj;
say $obj->{state};

Alternatywne rozwiązanie

Oto inny sposób:

package Magic {
    use Devel::Peek 'SvREFCNT';
    sub new { bless \my $foo }
    sub state { SvREFCNT ${$_[0]} }
}
use feature 'say';

my $obj = new Magic;
say $obj->state;
my $other = $obj;
say $obj->state;

Oto statemetoda (moglibyśmy uczynić ją atrybutem z dalszymi shenaniganami wiążącymi / przeciążającymi, ale to by skomplikowało rzeczy), która dosłownie liczy liczbę referencji do obiektu. Zatem, inaczej niż w pierwszym rozwiązaniu, faktycznie musisz przypisać $objdo normalnej zmiennej, która może zawierać odwołanie do obiektu, aby zmienić stan.

Ilmari Karonen
źródło
5

JavaScript

Ok, więc stworzyłem krótszą wersję, która działa jako SSCCE, ale nie próbuje już poprawnie parsować JavaScript, więc zliczanie referencji może nie działać po umieszczeniu w bardziej złożonym skrypcie.

(function run () {
    var lineOne = getLine (1), a, b, x, y, z;
    var x = {
        get state () {
            var x=/([a-z]+)\s*=\s*([a-z]+)/,c;
            return 1 + Object.keys (c = run.toString ().split ('\n').slice (0,getLine (2)).filter (function (a) {return (x.test (a))}).reduce (function (a,b,c,d) {var r=b.match (x),t=r[2];while (a[t]){t=a[t]};a[r[1]]=t;return a}, {v:0})).reduce (function (a,b) {return (c[b]=="x"?1:0) + a},0)
        }
    };
    console.log (x.state);  //1
    console.log (x.state);  //1
    y = x;
    console.log (x.state);  //2
    z = y;
    console.log (x.state);  //3    
    a = z;
    b = a;
    console.log (x.state);  //5
    a = null;
    console.log (x.state);  //4
    b = null;
    console.log (x.state);  //3
})() //1 1 2 3 5 4 3 

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}
C5H8NNaO4
źródło
2
Chcesz wyjaśnić, co robisz?
Ryan
5
... co to jest na świecie? O_o
Klamka
@Doorknob Moduł pobierający, który zwraca wynik wywołania funkcji, która zlicza, jak często nazwa identyfikatora jest określana jako rval, w wyrażeniu przypisania, w obrębie danego tekstu źródłowego do danej linii, przekazując jej źródło funkcji zamykającej i linię getter został wywołany jako argument. Cała reszta to niechlujny prowizoryczny tokenizer. --- Nie wiem, jak inaczej mam to nazwać . Innymi słowy. Innymi słowy: moduł pobierający zlicza liczbę przypisań referencji do x aż do linii, z której został wywołany, reszta jest nieukończonym tokenizerem.
C5H8NNaO4
1
Najdłuższe… i najszersze!
Nicolas Barbulesco
1
@NicolasBarbulesco Zrobiłem to krócej
C5H8NNaO4
4

Pyton

To trochę oszukuje, ale co powiesz na:

import gc
class A(object):
    @property
    def state(self):
        return len(gc.get_referrers(self))

a = A()
print a.state
b = {"x": a}
print a.state
a.y = a
print a.state
del a
print b["x"].state
James_pic
źródło
4

C ++ 11

chociaż można to rozszerzyć na inne języki, które obsługują ukryte / jawne destruktory

#include <iostream>
using namespace std;

class Foo {
    int *ptr;
public:
    Foo() {
        ptr = new int(0);
    }   
    int state() {
        return *ptr;
    }
    ~Foo() {
        (*ptr)++;
    }
};
int main() {
    Foo a, b;
    cout << a.state() << " " << b.state() << "\n";
    {
        Foo c, d;
        c = a;
        d = b;
    }
   cout << a.state() << " " << b.state()  << "\n";

   return 0;
}

Domyślny operator przypisania wykonuje płytką kopię. Zatem obiekt odbierający nadal jest właścicielem wskaźnika, a wszelkie zmiany pośrednio wpływają na obiekt oryginalny;

Abhijit
źródło
1
Tak, newbez jednego deletew programie. Chociaż do tego zadania wydaje mi się, że jest wystarczająco dobry :)
Ruslan
Jakie są wyniki?
Nicolas Barbulesco
1
Z tego, co rozumiem (C ++ jest daleko…), tutaj przypisanie nie zmienia stanu . W przeciwnym razie przesuń coutlinię w górę przed }i powiedz, czy to działa. :-)
Nicolas Barbulesco
4

Scala

Konwersje niejawne pozwalają to osiągnąć podczas przypisywania do normalnej zmiennej lokalnej:

import scala.language.implicitConversions

class Obj {
  var counter = 0
}

implicit def o2s(x: Obj): String = {
  x.counter += 1
  x.toString
}

val obj = new Obj
println(obj.counter)
val s: String = obj
println(obj.counter)

Możesz to zrobić również na podstawie wnioskowanych typów:

var s = ""
s = obj

Możesz także użyć niestandardowej metody ustawiającej, chociaż wymaga to, aby wartość L była polem:

object L {
  var _value = new Obj
  def value = _value
  def value_=(x: Obj): Unit = {
    _value = x
    x.counter += 1
  }
}

val obj = new Obj
println(obj.counter)
L.value = obj
println(obj.counter)
Dan Getz
źródło
3

re

struct Obj {
    int state;

    void opAssign (ref Obj other) {
        ++other.state;
    }
}

void main () {
    import std.stdio;

    Obj obj, lvalue;
    writeln(obj);
    lvalue = obj;
    writeln(obj);
}

Wydajność:

Obj(0)
Obj(1)
Hugo Dubé
źródło
3

Rubin

Zgodnie z obietnicą, oto odpowiedź, która zainspirowała pytanie.

obj = Class.new { def self.state; to_s[/</] ? "Has not been assigned\n" : "Assigned to #{to_s}"; end }

print obj.state

LValue = obj

print obj.state

Class.newtworzy anonimową klasę. Wywołanie to_sanonimowej klasy daje domyślną reprezentację ciągu obiektów, która wygląda #<Class:0x007fe3b38ed958>. Jednak po przypisaniu klasy do stałej to_sstaje się ona stała. W Ruby stała jest zmienną, która zaczyna się od dużej litery, więcobj jak odwołanie do klasy, która pozwala zachować anonimowość.

Mój kod jest zawijany to_sw statemetodzie, więc wynik staje się

Has not been assigned
Assigned to LValue

W przeciwieństwie do większości rozwiązań tutaj, działa to tylko raz: przypisanie objdo innej stałej nie zmieni jej reprezentacji łańcuchowej i żadna z nich nie przypisze nowej wartości LValue.

histocrat
źródło
3

W Javie

Myślałem, że to niemożliwe w Javie. Ale…

Główna klasa:

public class MyAppOfCats {

  public static void main(String[] args) {
    Cat tom = new Cat();
    System.out.println(tom.state()); 
    // Output : NOT-BEST-CAT
    Cat.bestCat = tom;
    System.out.println(tom.state());
    // Output : BEST-CAT
  }

}

Klasa Cat:

public class Cat {

  static Cat bestCat;

  public Cat() {
    super();
  }

  public String state() {
      return ((this == Cat.bestCat) ? "BEST-CAT" : "NOT-BEST-CAT");
  }

}

Inspiruje mnie @tbodt.

Nicolas Barbulesco
źródło
1
Wiem, że to nie jest gra w golfa, ale zdajesz sobie sprawę, że możesz po prostu usunąć konstruktora i nadal jest tak samo, prawda?
David Conrad
2
To nie jest „obiekt, którego stan zmienia się przy przypisaniu”. To jest manipulowanie wartością globalną, a następnie drukowanie czegoś na jej podstawie. Nie różni się niczym od Cat.x = 2drukowania Cat.x.
Chris Hayes,
@Chris - stan obiektu oparty jest na „wartości globalnej”. Zatem stan obiektu zmienia się przy przypisaniu. Pytanie brzmi ;-), że stan może być deterministyczną, idempotentną metodą. Moja metoda state () jest taką metodą.
Nicolas Barbulesco
Nie, stan obiektu zmienia się w tym konkretnym przydziale . Gdybym to zrobił, Cat otherCat = tomstan w ogóle by się nie zmienił. Trudno mi uwierzyć, że jest to zgodne z literą lub duchem zasad.
Chris Hayes
@Chris - Oczywiście obiekt zmienia się w tym zadaniu! Pytanie dotyczy obiektu, którego stan zostanie zmieniony przez przypisanie. Nie dla obiektu, którego stan może zostać zmieniony przez dowolne przypisanie.
Nicolas Barbulesco
3

C ++

To zachowanie jest faktycznie określone w standardzie (i dlatego zostało wycofane).

#include<iostream>
#include<memory>
int main()
{
    std::auto_ptr<int> a(new int(0));
    std::cout<<a.get()<<'\n';
    std::auto_ptr<int> b = a;
    std::cout<<a.get()<<'\n';
}

Wydajność

some address
0

Proces, który to powoduje, jest taki sam jak odpowiedź Abhijita, ale nie wymaga odpowiedzi std::movetakiej samej jak odpowiedź marinusa, ale używa standardowej klasy zamiast definiować ją sam.

Edycja: Dodaję wyjaśnienie. Na wyjściu „jakiś adres” będzie w rzeczywistości wartością szesnastkową dla adresu przydzielonej liczby całkowitej. std::auto_ptrzwalnia wskaźnik sklepów po przypisaniu do innego auto_ptri ustawia wskaźnik wewnętrzny na 0. Wywołanie get()pobiera dostęp do wskaźnika sklepów.

JKor
źródło
Podejrzewam, że „wyjście” tutaj nie jest prawdziwym wyjściem.
Nicolas Barbulesco
Czy możesz wyjaśnić, co to ma zrobić? Zwłaszcza metoda get()? Dlaczego zwraca 0 na końcu?
Nicolas Barbulesco
@Nicholas yep. To wyjście nie jest prawdziwym wyjściem, ale bardziej ogólnym wyjściem (ja również nie miałem dostępu do kompilatora, więc nie miałem wtedy przykładu prawidłowego adresu).
JKor
1
Hm, ta kompilacja nie działa na gcc 4.8.
Michael Hampton,
1
Naprawiłem błędy kompilacji. Nadal są ostrzeżenia, jeśli kompilujesz dla c ++ 11, ponieważ auto_ptrjest przestarzały.
JKor
3

Pyton

import sys
class K:state = property(sys.getrefcount)
pppery
źródło
2

Python 2.x

Nie mogłem znaleźć odpowiedniego sposobu na zrobienie tego bez zdefiniowania dodatkowej klasy.

class State(object):
    def __init__(self):
        self.state = 0
    def __set__(self, obj, other):
        # Keep different references
        other.state += 1
        self.state += 2

class Program(object):
    obj, value = State(), State() # Create two State-objects
    def __init__(self):
        print "Before assignment:", self.obj.state, self.value.state # 0 0
        self.value = self.obj # Set value to obj (supposedly)
        print "After  assignment:", self.obj.state, self.value.state # 1 2
        self.value = self.obj
        print "2nd    assignment:", self.obj.state, self.value.state # 2 4

Program()
patrz
źródło
2

Jawa

Wszystkie pozostałe rozwiązania wykorzystują formę przeciążenia operatora w ich języku. Java nie ma przeciążenia operatora, więc pomyślałem, że utknąłem. Ale coś wymyśliłem.

Oto główna klasa:

public class Program {
    public static void main(String[] args) {
        Thing thing = new Thing(0);
        System.out.println(thing.getState());
        Thing.otherThing = thing;
        Thread.sleep(1);
        System.out.println(thing.getState());
    }
}

Jest kilka podejrzanych linii, ale nie zrobiliby nic, gdyby Thingklasa była całkowicie normalna. To nie jest:

public class Thing {
    private int state;

    public Thing(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }

    // Please do your best to ignore the rest of this class.
    public static volatile Thing otherThing;
    static {
        Thread t = new Thread() {
            public void run() {
                Thing t = otherThing;
                while (true)
                    if (t != otherThing) {
                        t = otherThing;
                        t.state++;
                    }
            }
        };
        t.setDaemon(true);
        t.start();
    }
}

Nie ma gwarancji, że zadziała z powodu wątków, ale przetestowałem go na JDK 1.8u5 i tam działa.

tbodt
źródło
@KyleKanos Pozbyłem się wszystkich znaków Unicode> U + 00FF
tbodt
1

Common Lisp

Stan definiuję jako liczbę zmiennych specjalnych związanych z wektorem. Tak więc przypisanie do specjalnej zmiennej zmienia stan.

(defgeneric state (object)
  (:documentation "Get the state of this object."))

(defmethod state ((object vector))
  ;; The state of a vector is the number of symbols bound to it.
  (let ((count 0))
    ;; Iterate each SYM, return COUNT.
    (do-all-symbols (sym count)
      ;; When SYM is bound to this vector, increment COUNT.
      (when (and (boundp sym) (eq (symbol-value sym) object))
    (incf count)))))

(defparameter *a* #(this is a vector))
(defparameter *b* nil)
(defparameter *c* nil)

(print (state *a*))
(setf *b* *a*)
(print (state *a*))
(print (state *a*))
(setf *c* *a*)
(print (state *a*))

Wydajność:

1 
2 
2 
3 

Działa tylko z przypisaniami do zmiennych specjalnych, nie do zmiennych leksykalnych, ani do szczelin w obiekcie.

Uważaj na to do-all-symbols przegląda wszystkie pakiety, więc pomija zmienne, które nie mają pakietu. Może podwójnie policzyć symbole, które istnieją w więcej niż jednym pakiecie (gdy jeden pakiet importuje symbol z innego pakietu).

Rubin

Ruby jest prawie taki sam, ale definiuję stan jako liczbę stałych odnoszących się do tablicy.

class Array
  # Get the state of this object.
  def state
    # The state of an array is the number of constants in modules
    # where the constants refer to this array.
    ObjectSpace.each_object(Module).inject(0) {|count, mod|
      count + mod.constants(false).count {|sym|
        begin
          mod.const_get(sym, false).equal?(self)
        rescue NameError
          false
        end
      }
    }
  end
end

A = %i[this is an array]
puts A.state
B = A
puts A.state
puts A.state
C = A
puts A.state

Wydajność:

state-assign.rb:9:in `const_get': Use RbConfig instead of obsolete and deprecated Config.
1
2
2
3

Jest to uogólnienie odpowiedzi histocrata na obiekty Ruby, które nie są klasami ani modułami. Ostrzeżenie pojawia się, ponieważ stała Config automatycznie ładuje kod, który utworzył ostrzeżenie.

kernigh
źródło
0

C ++

Wynik może się różnić na różnych platformach. Testowany na ideonie .

#include <iostream>
#include <cassert>
// File format: [ciiiiciiii...] a char (1 byte) followed by its state (4 bytes)
// Each group takes 5 bytes
char Buffer[30]; // 5*6, six groups

struct Group {
    char c;
    int state;
};

int main(void) {
    assert(sizeof(char) == 1);
    assert(sizeof(int) == 4);

    Group& first_group = *(Group*)(&Buffer[0]); // Group 1 is at 0
    Group& second_group = *(Group*)(&Buffer[5]); // Group 2 is at 5

    first_group.c = '2';
    first_group.state = 1234;

    std::cout << first_group.state << std::endl;

    second_group = first_group;

    std::cout << first_group.state << std::endl;

    return 0;
}

Wydajność:

1234
13010
jingyu9575
źródło
0

DO#

class A
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
}
class B
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
    public static implicit operator A(B b) { b.N = -b.N; return new A { N = b.N }; }
}
public static void Test()
{
    A a = new A { N = 1 };
    B b = new B { N = 2 };
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
    a = b;
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
}

Wydajność:

a is 1, b is 2
a is 1, b is 2
a is -2, b is -2
a is -2, b is -2
ClickRick
źródło
Co to robi? Czy to przeciąża operatora =?
Nicolas Barbulesco
@Nicolas Niezupełnie. To jest podczas rzucania z a Bna A, ponieważ implicit operator A(B b)ma skutki uboczne.
ClickRick