Bob Smith
Bob Smith

Reputation: 841

Pass by ref and typecast at the same time

Is there a way to do this in C#?

private void Caller()
{
  MyControl c = new MyControl();
  Callee(ref c);                       //Here I want to cast c as Control and pass by ref
}

private void Callee(ref Control c)
{

}

In the generics example, how does it infer T = MyControl? Can you please explain? I am a newbie to generics

Upvotes: 1

Views: 322

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062770

First, I'd question whether you need ref - it seems unusual; that would mean you intend to re-assign the variable inside the method? (different to changing properties of the passed instance).

For ref, it must be an exact match; you could use:

Control tmp = c;
Callee(ref tmp);
c = (MyControl) tmp;

Alternatively, consider generics:

private void Callee<T>(ref T c) where T : Control
{ ... }

Then you can use Callee(ref c) and it will infer T = MyControl

(updated re comment)

In the generic example, we declare Callee as a generic method "of T", where T is at least a Control. This "at least" ensures that we still have access to all the members of Control inside the method (since any subclass of Control still has those members).

Generics act a bit like templates (but not quite). The caller gets to specify the T when calling the method. So the caller could use Callee<Control>(...), which would compare to calling your existing Callee(ref Control c). Or they could use Callee<MyControl>(...), which is like calling Callee(ref MyControl c) - in both cases the T gets substituted throughout the method.

However, the C# compiler is intelligent enough that often you don't need to tell it the bit in angle brackets; it can see that you are passing a MyControl, so it will assume (unless you tell it otherwise) that it should use T = MyControl - this is called generic type inference. The point here is that it makes it easy to use ref with subclasses of the data.

Upvotes: 3

Rauhotz
Rauhotz

Reputation: 8140

No, that is not possible and there's a good reason for that. Imagine that you change c in Callee and assign another descendent of Control to it that is NOT an instance of MyControl.

Upvotes: 1

Related Questions