c# - Does a variable of an interface type act as value type if the underlying implementation is a struct? -
i looking @ this question, , aside rather odd way enumerate something, op having trouble because enumerator struct. understand returning or passing struct around uses copy because value type:
public mystruct getthingbutactuallyjustcopyofit() { return this.mystructfield; }
or
public void pretendtodosomething(mystruct thingy) { thingy.desc = "this doesn't work expected"; }
so question if mystruct implements imyinterface (such ienumerable), these types of methods work expected?
public struct mystruct : imyinterface { ... } //will caller able modify property of returned imyinterface? public imyinterface actuallystruct() { return (imyinterface)this.mystruct; } //will interface pass in value changed? public void setinterfaceprop(imyinterface thingy) { thingy.desc = "the implementing type struct"; }
yes, code work, needs explanation, because there whole world of code not work, , you're trip unless know this.
before forget: mutable structs evil. ok, out of way, let's move on.
let's take simple example, can use linqpad verify code:
void main() { var s = new mystruct(); test(s); debug.writeline(s.description); } public void test(imyinterface i) { i.description = "test"; } public interface imyinterface { string description { get; set; } } public struct mystruct : imyinterface { public string description { get; set; } }
when executing this, printed?
null
ok, why?
well, problem line:
test(s);
this in fact box struct , pass boxed copy method. you're modifying boxed copy, not original s
variable, never assigned anything, , still null
.
ok, if change 1 line in first piece of code:
imyinterface s = new mystruct();
does change outcome?
yes, because you're boxing struct here, , use boxed copy. in this context behaves object, you're modifying boxed copy , writing out contents of boxed copy.
the problem crops whenever box or unbox struct, copies live separate lives.
conclusion: mutable structs evil.
i see 2 answers using ref
here now, , barking wrong tree. using ref
means you've solved problem before added ref
.
here's example.
if change test
method above take ref
parameter:
public void test(ref imyinterface i)
would change anything?
no, because code invalid:
var s = new mystruct(); test(ref s);
you'll this:
the best overloaded method match 'userquery.test(ref userquery.imyinterface)' has invalid arguments
argument 1: cannot convert 'ref userquery.mystruct' 'ref userquery.imyinterface'
and change code this:
imyinterface s = new mystruct(); test(ref s);
but you're example, having added ref
, showed not necessary change propagate back.
so using ref
orthogonal, solves different problems, not one.
ok, more comments regarding ref
.
yes, of course passing struct around using ref
indeed make changes flow throughout program.
that not question about. question posted code, asked if work, , would. in particular variant of code work. it's easy trip up. , pay particular note question regarding structs , interfaces. if leave interfaces out of it, , pass struct around using ref
, have? a different question.
adding ref
not change question, nor answer.
Comments
Post a Comment