new keyword in method signature not working?

Started by Thirite, January 11, 2017, 11:43:52 PM

Previous topic - Next topic

Thirite

I'm trying to override a method from the Building_Bed class in my derived class "Building_Crib" using the 'new' keyword, but when I run the game it acts like the new method doesn't exist. Here's my code:

namespace RimWorldChildren
{
public class Building_Crib : Building_Bed
{
public new IEnumerable<Pawn> AssigningCandidates {
get {
if (!base.Spawned) {
return Enumerable.Empty<Pawn> ();
}
List<Pawn> candidates = base.Map.mapPawns.FreeColonists.ToList();
foreach (Pawn candidate in candidates) {
if (candidate.ageTracker.CurLifeStageIndex > 2) {
candidates.Remove (candidate);
}
}
return candidates;
}
}

public new void TryAssignPawn (Pawn owner)
{
if(owner.ageTracker.CurLifeStageIndex < 2)
owner.ownership.ClaimBedIfNonMedical (this);
}
}
}


If I try to override a method that can use the "override" keyword it works fine. Any suggestions?

RawCode


Fluffy (l2032)

@Thirite;

Please read up on the difference between 'new' and 'override'. In a nutshell, if a method has keyword override, it will be used instead of the base method for all instances of the class the override is defined in (and it's descendants). This applies regardless of the current 'state' of the instance. The same is not true for methods not marked override, as they will be used only if the instance is recognized as the type the 'new' method was defined in. In fact, 'new' does pretty much nothing besides suppress warnings/errors from the compiler - which is the reason it's generally a bad idea to use it.

Small example, let's say we have two classes, CustomThing : Thing

public class Thing {
  public void virtual Foo(){
    // do A
  }
  public void Bar(){
    // do B
  }
}

public class CustomThing : Thing {
  public void override Foo(){
    // do C
  }
  public void new Bar(){
    // do D
  }
}


The distinction is in what happens if we call Foo or Bar on an instance of CustomThing that is cast to a Thing. This scenario applies to pretty much every custom Thing class in the game, including modded ones, as generally speaking the game keeps them all in IEnumerable<Thing> type iterators.


CustomThing cThing = new CustomThing();
cThing.Foo() // does C
cThing.Bar() // does D

Thing thing = cThing as Thing;
thing.Foo() // still does C!
thing.Bar() // does B!


Note that you can only override methods that were designated either virtual or abstract in their defining Type.

Thirite

Well fug. Looks like I didn't understand it as well as I thought.