M
MRe
Hi,
Is the following possible? It feels like it's possible - but for the
sake of example, I've made up something that isn't possible. Hopefully
it will explain my question, because I'm having a bit of trouble
putting it into words. I am able to do what I want by using reflection
(but would be interested in avoiding it) and I've included an example
of it too (below my first example).
Note: the only difference between the two examples is in the Link.find
method.
Thank you,
Kind regards,
Eliott
//////////// Desired (but non-compiling) "solution" ////////////
using System;
namespace Test
{
class Program
{
static void Main
( string[] args
){ new Program();
}
private Program()
{
// Create a link list using
// Link class (defined below)
Link list = new Link
( new Link
( new SpecialLink()
)
);
// Find the "special" link
SpecialLink specialness = null;
if(list.find<SpecialLink>
( ref specialness
)) specialness.unleash();
}
}
// A generic link
class Link
{
public Link()
{ _next = null;
}
public Link(Link next)
{ _next = next;
}
// Find a link that knows
// about some T type
public virtual bool find<T>
( ref T link
) where T : Link
{ if(_next != null)
return _next.find<T>
( ref link
);
return false;
}
private readonly Link _next;
}
// A less generic link
class SpecialLink : Link
{
public SpecialLink() : base()
{ }
public SpecialLink
( Link next
): base(next)
{ }
// My magical polymorphic generics
// say this overriding find will
// be called in the face of
// find<SpecialLink>(..). I
// arbitrarily imagine reuse of
// the "where" keyword to mean
// polymorphic generic override
public override bool find<T>
( ref T link
) where T : SpecialLink
{ link = this;
return true;
}
public void unleash()
{ Console.WriteLine("hi");
}
}
}
//////////// Undesired (but compiling) "solution" ////////////
using System;
namespace Test
{
class Program
{
static void Main
( string[] args
){ new Program();
}
private Program()
{
// Create a link list using
// Link class (defined below)
Link list = new Link
( new Link
( new SpecialLink()
)
);
// Find the "special" link
SpecialLink specialness = null;
if(list.find<SpecialLink>
( ref specialness
)) specialness.unleash();
}
}
// A generic link
class Link
{
public Link()
{ _next = null;
}
public Link(Link next)
{ _next = next;
}
// Find a link that knows
// about some T type
public virtual bool find<T>
( ref T link
) where T : Link
{ // "If it's not broken, don't
// fix it!" depends on the
// definition of "broken."
// ..and this needs a fixin'
if(this is T)
{ link = (T)this;
return true;
}
if(_next != null)
return _next.find<T>
( ref link
);
return false;
}
private readonly Link _next;
}
// A less generic link
class SpecialLink : Link
{
public SpecialLink() : base()
{ }
public SpecialLink
( Link next
): base(next)
{ }
public void unleash()
{ Console.WriteLine("hi");
}
}
}
Is the following possible? It feels like it's possible - but for the
sake of example, I've made up something that isn't possible. Hopefully
it will explain my question, because I'm having a bit of trouble
putting it into words. I am able to do what I want by using reflection
(but would be interested in avoiding it) and I've included an example
of it too (below my first example).
Note: the only difference between the two examples is in the Link.find
method.
Thank you,
Kind regards,
Eliott
//////////// Desired (but non-compiling) "solution" ////////////
using System;
namespace Test
{
class Program
{
static void Main
( string[] args
){ new Program();
}
private Program()
{
// Create a link list using
// Link class (defined below)
Link list = new Link
( new Link
( new SpecialLink()
)
);
// Find the "special" link
SpecialLink specialness = null;
if(list.find<SpecialLink>
( ref specialness
)) specialness.unleash();
}
}
// A generic link
class Link
{
public Link()
{ _next = null;
}
public Link(Link next)
{ _next = next;
}
// Find a link that knows
// about some T type
public virtual bool find<T>
( ref T link
) where T : Link
{ if(_next != null)
return _next.find<T>
( ref link
);
return false;
}
private readonly Link _next;
}
// A less generic link
class SpecialLink : Link
{
public SpecialLink() : base()
{ }
public SpecialLink
( Link next
): base(next)
{ }
// My magical polymorphic generics
// say this overriding find will
// be called in the face of
// find<SpecialLink>(..). I
// arbitrarily imagine reuse of
// the "where" keyword to mean
// polymorphic generic override
public override bool find<T>
( ref T link
) where T : SpecialLink
{ link = this;
return true;
}
public void unleash()
{ Console.WriteLine("hi");
}
}
}
//////////// Undesired (but compiling) "solution" ////////////
using System;
namespace Test
{
class Program
{
static void Main
( string[] args
){ new Program();
}
private Program()
{
// Create a link list using
// Link class (defined below)
Link list = new Link
( new Link
( new SpecialLink()
)
);
// Find the "special" link
SpecialLink specialness = null;
if(list.find<SpecialLink>
( ref specialness
)) specialness.unleash();
}
}
// A generic link
class Link
{
public Link()
{ _next = null;
}
public Link(Link next)
{ _next = next;
}
// Find a link that knows
// about some T type
public virtual bool find<T>
( ref T link
) where T : Link
{ // "If it's not broken, don't
// fix it!" depends on the
// definition of "broken."
// ..and this needs a fixin'
if(this is T)
{ link = (T)this;
return true;
}
if(_next != null)
return _next.find<T>
( ref link
);
return false;
}
private readonly Link _next;
}
// A less generic link
class SpecialLink : Link
{
public SpecialLink() : base()
{ }
public SpecialLink
( Link next
): base(next)
{ }
public void unleash()
{ Console.WriteLine("hi");
}
}
}