Verifying code against template patterns using reflection - c#

I am working on a large project where a base class has thousands of classes derived from it (multiple developers are working on them). Each class is expected to override a set of methods. I first generated these thousands of class files with a code template that conforms to an acceptable pattern. I am now writing unit tests to ensure that developers have not deviated from this pattern. Here is a sample generated class:
// Base class.
public abstract partial class BaseClass
{
protected abstract bool OnTest ();
}
// Derived class. DO NOT CHANGE THE CLASS NAME!
public sealed partial class DerivedClass_00000001: BaseClass
{
/// <summary>
/// Do not modify the code template in any way.
/// Write code only in the try and finally blocks in this method.
/// </summary>
protected override void OnTest ()
{
bool result = false;
ComObject com = null;
// Declare ALL value and reference type variables here. NOWHERE ELSE!
// Variables that would otherwise be narrowly scoped should also be declared here.
// Initialize all reference types to [null]. [object o;] does not conform. [object o = null;] conforms.
// Initialize all value types to their default values. [int x;] does not conform. [int x = 0;] conforms.
try
{
com = new ComObject();
// Process COM objects here.
// Do NOT return out of this function yourself!
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
}
return (result);
}
}
In the unit tests, I have been able to verify the following via reflection:
The class derives from [BaseClass] and does not implement any interfaces.
The class name conforms to a pattern.
The catch block has not been filtered.
No other catch blocks have been added.
No class level fields or properties have been declared.
All method value type variables have been manually initialized upon declaration.
No other methods have been added to the derived classes.
The above is easily achieved via reflection but I am struggling with asserting the following list:
The catch block re-throws the caught exception rather than wrapping it or throwing some other exception.
The [return (result);] line at the end has not been modified and no other [return (whatever);] calls have been added. No idea how to achieve this.
Verify that all reference types implementing IDisposable have been disposed.
Verify that all reference types of type [System.__ComObject] have been manually de-referenced and set to [null] in the finally block.
I have thought about parsing the source code but I don't like that solution unless absolutely necessary. It is messy and unless I have expression trees, almost impossible to guarantee success.
Any tips would be appreciated.

Some thoughts:
If the methods need to be overriden, why are they virtual instead of abstract?
Code that should not be changed doesn't belong in the derived class. It belongs in the base class.
catch { throw; } is useless. Remove it.
Returning a boolean value from a void method causes a compiler error.
Setting local variables to null is useless.
Not all reference types implement IDisposable.
Generally: Most of your requirements seem to have no business value.
Why prohibit implementation of an interface?
Why prohibit declaration of other methods?
Why prohibit catch clauses?
etc.
You should really think about what your actual business requirements are and model your classes after them. If the classes need to fulfill a certain contract, model that contract. Leave the implementation to the implementor.
About the actual questions raised:
You can't use reflection here. You can either analyze the original source code or the IL code of the compiled assembly.
Both options are pretty tricky and most likely impossible to achieve within your limited time. I am positive that fixing the architecture would take less time than implementing one of those options.

You could try to use Roslyn CTP here if the fully automated code analysis is what you really need. It has more advanced syntax and semantics analysis than reflection does. But it is still a lot of work. Working directly with developers, not with their code, preparing templates, guidelines may be more time efficient.

While I'm sure you have a very good reason for such rigid requirements... have you considered passing a Lambda's/Delegates/Action to the Test function instead?
Can't solve everything, but would more logically give you some of the behaviours you want (e.g. can't return, can't have class level variables, can't write code anywhere but specified).
Biggest concern with it would be captured variables... but there may be work arounds for that.
Example Code:
//I'd make a few signatures....
bool OnTest<T1, T2> (Action<ComObject, T1, T2> logic, T1 first, T2 second)
{
bool result = false;
ComObject com = null;
//no checks needed re parameters
//Can add reflection tests here if wanted before code is run.
try
{
com = new ComObject();
//can't return
logic(com, first,second);
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
//If you want, we can check each argument and if it is disposable dispose.
if (first is IDisposable && first != null) ((IDisposable) first).Dispose();
...
}
return (result); //can't be changed
}
No idea if this'll work, but it's just a thought. Oh, and as a thought it's not thorough or tested - I'd expect you to develop it drastically.

Related

Can A subclass be downcast while sent as a parameter to an overloaded function

I have a superClass called Block and another 3 subclasses. the class I want to implement contains 3 overloaded functions each one takes an object of one of the subclasses as a parameter. When I use one of these function, I only have a Block object (An object from the superClass). My question is what is the cleanest way to choose which function to call.
What I did until now is if conditions on the object type then casting it. but it seems unclean.
Those are the overloaded functions.
public void WriteBlock(TableBlock block) { }
public void WriteBlock(TextBlock block) { }
public void WriteBlock(ListBlock block) { }
And This is The function I want to implement.
public void WriteBlocks(List<Block> blocks)
{
BlockWriter w = new BlockWriter();
foreach (var block in blocks)
{
w.WriteBlock(block);
}
}
Note that I have no access on the Blocks classes.
Yes, it is possible using the dynamic type which allows for this.
If you use:
foreach (var block in blocks)
{
w.WriteBlock(block as dynamic);
}
It should call the intended WriteBlock overload.
This is described in greater length in another question: https://stackoverflow.com/a/40618674/3195477
And also here: method overloading and dynamic keyword in C#.
Caveats:
I am not sure if there is any runtime penalty associated with this type of dynamic "cast".
Also whenever I see this pattern it makes me wonder if the class hierarchy could be improved. i.e., should whatever WriteBlock will do actually be moved inside the Block classes? That might be "more polymorphic". Also using dynamic could be a somewhat fragile approach, as you can add new Block derived types and forget to an an overloaded WriteBlock for them, which may cause an error. (This is more evidence that some of WriteBlock should be incorporated into the Block classes themselves).
For instance, add a virtual PrepareForWriting() to the base Block class, which returns a BlockWritable. Then you only need one WriteBlock(BlockWritable data) to do the writing work. BlockWritable could be a string, Json, XML, etc. This assumes you are able to modify the Block classes (which it seems you cannot).
No. Given this:
public void WriteBlocks(List<Block> blocks)
the only thing the compiler knows about each item in the list is that it is a Block. That's all it should know. That's what makes polymorphism possible. There can be any number of classes that inherit from Block, but within this context those distinctions don't matter.
But if all the compiler knows is that each item is a Block, it can't know whether any individual item might be a TableBlock, TextBlock, or some other inherited type. If, at compile time, it doesn't know what the runtime type will be, it can't know whether there even is an overload for that specific type.
Suppose what you're trying to do could compile, because you have an overload for every type that inherited from Block. What would or should happen if you added a new type - class PurpleBlock : Block - and there was no overload for it? Should this no longer compile just because you added a new type?
If the method that calls WriteBlocks knows what sort of Block is in the list, then it can supply that information:
public void WriteBlocks<TBlock>(List<TBlock> blocks) where TBlock : Block
Now you can call WriteBlock<TextBlock>(listOfTextBlocks) and the compiler will know that each item in the list is a TextBlock, not just a Block.
It follows, then, that BlockWriter would have to be generic also so that you could have different implementations for different types of Block. It might make more sense to inject it. Either way, you're likely to perceive that you've "moved" the problem. If the class that calls WriteBlocks "knows" the type of the Block, then it might make more sense for that method to determine the type of BlockWriter to use.
As mentioned in your comment, the list might include different types of Block, not just one. That requires either a method or a class that returns a specific BlockWriter depending on the type of Block. That means runtime type-checking, which isn't ideal, but it's not too bad if you keep it in one place.
Here's a simple example:
public class BlockWriterFactory
{
public BlockWriter GetBlockWriter(Block block)
{
if (block is TextBlock)
return new TextBlockWriter();
if (block is TableBlock)
return new TableBlockWriter();
if (block is ListBlock)
return new ListBlockWriter();
// this could be a "null" class or some fallback
// default implementation. You could also choose to
// throw an exception.
return new NullBlockWriter();
}
}
(A NullBlockWriter would just be a class that does nothing when you call its Write method.)
This sort of type-checking isn't ideal, but at least this keeps it isolated into one class. Now you can create (or inject) an instance of the factory, and call GetBlockWriter, and the rest of your code in that method still wouldn't "know" anything about the different types of Block or BlockWriter.
BlockWriter w = new BlockWriter();
would become
BlockWriter w = blockWriterFactory.GetBlockWriter(block);
...and then the rest would still be the same.
That's the simplest possible factory example. There are other approaches to creating such a factory. You could store all of your implementations in a Dictionary<Type, BlockWriter> and attempt to retrieve an instance using block.GetType().

Would you consider changing the interface or using an adapter here?

I have an interface that returns an Enumerable of a type.
public interface IMapper
{
IEnumerable<IContract> Get(params object[] objects);
}
That basically takes one or more parameters whose type is also unknown and returns an Enumerable of any type that implements IContract. Feel free to suggest an alternative for this.
Now this looks simple enough and works. However, here's a scenario where it always returns one object (of type IContract). I can't change the fact that it returns only one object.
var escalationMapper = _factory.GetEscalationMapper();
//we only get one object with a list of triggers but the interface returns a list. Change the interface?
var escalations = escalationMapper.Get(trackingGroupCode);
_factory.Release(escalationMapper);
var contracts = escalations as IList<IContract> ?? escalations.ToList();
response = Request.CreateResponse(!contracts.Any()
? HttpStatusCode.NotFound : HttpStatusCode.OK, contract);
The line of code we're interested is what follows the comment because I don't feel comfortable returning just one object and calling it a list. There are other usages of the Get() method that returns lists proper This just happened to return at most 1 object..
Is it reasonable to return a single object as a list, or is there a better way to implement this?
Like I said in the comments, there is nothing wrong design-wise with your code. Even if the particular place where you call Get is guaranteed to return at most a single item within the returned list, that doesn't mean it's going to be guaranteed everywhere else that calls IMapper.Get.
If you really want to simplify it so that it returns the single object instead of a one-length list, though, I wouldn't recommend changing the interface to have an additional method, either. This would break all classes that implement IMapper and force you to implement that new method, even in places where the new method wouldn't add anything useful. This would be an especially big problem if anyone else uses your code for their own purposes, as it would force them to perform the rewrite as well.
One thing you could do to get around that issue, however, is to instead declare the new method as an extension method:
public static class IMapperExtensions
{
public static IContract GetSingle(this IMapper mapper, params object[] objects)
{
return mapper.Get(objects).FirstOrDefault();
}
}
Then you can call it like so:
var escalation = escalationMapper.GetSingle(trackingGroupCode);
This will give you the functionality you need without breaking any existing implementations of your interface.
I agree with #Abion47 and #chrylis comments - 0 or 1 items is a perfectly valid case for an collection of items.
However - if you disagree and still want a way to convey a single element without IEnumerable semantics, you could overload Get with a method that takes a single object and returns a single IContract. This would take precedence over the params[] overload, since object would be a better match for a single input than params[] object.
This would look like:
public interface IMapper
{
IContract Get(object input);
IEnumerable<IContract> Get(params object[] input);
}
Assuming a null value means not found, your calling code would become:
var escalationMapper = _factory.GetEscalationMapper();
//we only get one object with a list of triggers but the interface returns a list. Change the interface?
var escalation = escalationMapper.Get(trackingGroupCode);
_factory.Release(escalationMapper);
response = Request.CreateResponse(contract == null ? HttpStatusCode.NotFound : HttpStatusCode.OK, contract);
I have to caution that it feels odd suggesting this, and I think it introduces dishonesty into the interface. I also think there is great potential to break any existing code that also calls the interface with a single input.
As for replacing object, you could always add some marker interface like IContractInput and pass that into Get instead of object:
public interface IContractInput { /* Intentionally empty */ }
And then, mark any input class with IContractInput:
public class SomeInput : IContractInput { /* implementation.. */ }
That way the methods could be strongly typed to take IContractInput instead of a generic object type.
It's a tradeoff. The goal is to fit the type expected by the client. The tradeoff is between 1) having an additional class and 2) forcing an existing type to change.
The pro of 1) is that an existing type remains intact (assuming it does presently make the most sense as the type it is, returning a single IContract); the con of 1) is that it requires more code and more dependencies.
The pro of 2) is that code size and number of dependencies remain lower; the con of 2) is that you subvert the project's types design by changing a type to return a list that will always contain a single element, purely for the sake of the client's expectations.
In strongly typed languages, the types system is intended to be there as an aid to the programmer. The greater verbosity buys the benefits of the type system, and subverting that system doesn't help very much with reducing the verbosity, yet loses the benefits of that type system. As such, I would resolve this in strongly-typed languages with an adapter, not by changing the interface.
In other words, resolve the situation with the principle of least surprise ( https://en.wikipedia.org/wiki/Principle_of_least_astonishment ). If another programmer on the project (or you, yourself, in some months' time) would ordinarily expect an instance of EscalationMapper to return a sole IContract, and so would be surprised to see it return an IEnumerable, then use an adapter ( https://en.wikipedia.org/wiki/Adapter_pattern ). If, conversely, they'd be surprised to see it return a single item, then change the interface.

Expected behavior of IEnumerable member of class when items are added via interface function

I have a class, which has an IEnumerable. On this class there is an interface function to Add new items to this IEnumerable collection. The way this interface Add function works is by first converting the current collection to a list, adding a new one, and converting it back to an IEnumerable. Now the instance of the IEnumerable has changed, and all references to this IEnumerable member of the class are 'decoupled'.
Is this simply a matter of choice? Or is it desired behavior to keep the IEnumerable references coupled?
Are there coding guidelines for such behavior?
See the example code below which demonstrates the decoupling behavior:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var factory = new Factory();
factory.AddPackageId(1);
var referenceToPackageIds = factory.PackageIds;
factory.AddPackageId(1);
Console.WriteLine("referenceToPackageIds contains {0} packages.", referenceToPackageIds.Count());
Console.ReadKey();
}
}
class Factory
{
public IEnumerable<int> PackageIds
{
get
{
if (_PackageIds == null)
{
_PackageIds = new List<int>();
}
return _PackageIds;
}
set
{
//Do some sanity checks here... but left out for brevity.
_PackageIds = value;
}
}
private IEnumerable<int> _PackageIds;
public void AddPackageId(int packageId)
{
var list = PackageIds.ToList();
list.Add(packageId);
PackageIds = list.ToArray();
}
}
}
Your question is merely a special case of a more general question: if an object exposes a method whose return type provides a read-only view of something, is the returned view expected to be:
A view of an immutable snapshot, which will not change even if the object does.
A "live" read-only view of the object, which will show any changes made to the object
A view which will reflect the current state of the object as long as the object is not modified, but makes no promises with regard to behavior if it is.
In many cases, #3 will be the cheapest one for the method to provide, and it will fit most callers' needs. Callers should not expect a method to return #1 or #2 unless the documentation of the method explicitly specifies which; callers which are prepared for #3 will be satisfied with any of the above.
It's too bad the creators of Java and .NET were so opposed to Hungarian notation, since distinctions like the above would otherwise represent an excellent use for it. If a method returns IEnumerable<T>, nothing in the type system will indicate which of the above kinds of thing it returns, but such information is often vital when trying to write efficient and correct code. I would suggest that you affirmatively decide whether you wish to promise callers that the object you return will never change, or whether to explicitly refrain from making such a promise. Making the promise will allow some callers to be more efficient (since callers that want a snapshot will be able to use the returned object directly, rather than having to copy the contents to a new immutable object) but may compel future versions of the class to copy the contents of a mutable object for the purpose of returning them, when it would otherwise be able to simply return a read-only wrapper.

C# initial value in constructor OR class variable declaration? [duplicate]

I've been programming in C# and Java recently and I am curious where the best place is to initialize my class fields.
Should I do it at declaration?:
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
or in a constructor?:
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}
I'm really curious what some of you veterans think is the best practice. I want to be consistent and stick to one approach.
My rules:
Don't initialize with the default values in declaration (null, false, 0, 0.0…).
Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
If the value of the field changes because of a constructor parameter put the initialization in the constructors.
Be consistent in your practice (the most important rule).
In C# it doesn't matter. The two code samples you give are utterly equivalent. In the first example the C# compiler (or is it the CLR?) will construct an empty constructor and initialise the variables as if they were in the constructor (there's a slight nuance to this that Jon Skeet explains in the comments below).
If there is already a constructor then any initialisation "above" will be moved into the top of it.
In terms of best practice the former is less error prone than the latter as someone could easily add another constructor and forget to chain it.
I think there is one caveat. I once committed such an error: Inside of a derived class, I tried to "initialize at declaration" the fields inherited from an abstract base class. The result was that there existed two sets of fields, one is "base" and another is the newly declared ones, and it cost me quite some time to debug.
The lesson: to initialize inherited fields, you'd do it inside of the constructor.
The semantics of C# differs slightly from Java here. In C# assignment in declaration is performed before calling the superclass constructor. In Java it is done immediately after which allows 'this' to be used (particularly useful for anonymous inner classes), and means that the semantics of the two forms really do match.
If you can, make the fields final.
Assuming the type in your example, definitely prefer to initialize fields in the constructor. The exceptional cases are:
Fields in static classes/methods
Fields typed as static/final/et al
I always think of the field listing at the top of a class as the table of contents (what is contained herein, not how it is used), and the constructor as the introduction. Methods of course are chapters.
In Java, an initializer with the declaration means the field is always initialized the same way, regardless of which constructor is used (if you have more than one) or the parameters of your constructors (if they have arguments), although a constructor might subsequently change the value (if it is not final). So using an initializer with a declaration suggests to a reader that the initialized value is the value that the field has in all cases, regardless of which constructor is used and regardless of the parameters passed to any constructor. Therefore use an initializer with the declaration only if, and always if, the value for all constructed objects is the same.
There are many and various situations.
I just need an empty list
The situation is clear. I just need to prepare my list and prevent an exception from being thrown when someone adds an item to the list.
public class CsvFile
{
private List<CsvRow> lines = new List<CsvRow>();
public CsvFile()
{
}
}
I know the values
I exactly know what values I want to have by default or I need to use some other logic.
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = new List<string>() {"usernameA", "usernameB"};
}
}
or
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = GetDefaultUsers(2);
}
}
Empty list with possible values
Sometimes I expect an empty list by default with a possibility of adding values through another constructor.
public class AdminTeam
{
private List<string> usernames = new List<string>();
public AdminTeam()
{
}
public AdminTeam(List<string> admins)
{
admins.ForEach(x => usernames.Add(x));
}
}
What if I told you, it depends?
I in general initialize everything and do it in a consistent way. Yes it's overly explicit but it's also a little easier to maintain.
If we are worried about performance, well then I initialize only what has to be done and place it in the areas it gives the most bang for the buck.
In a real time system, I question if I even need the variable or constant at all.
And in C++ I often do next to no initialization in either place and move it into an Init() function. Why? Well, in C++ if you're initializing something that can throw an exception during object construction you open yourself to memory leaks.
The design of C# suggests that inline initialization is preferred, or it wouldn't be in the language. Any time you can avoid a cross-reference between different places in the code, you're generally better off.
There is also the matter of consistency with static field initialization, which needs to be inline for best performance. The Framework Design Guidelines for Constructor Design say this:
✓ CONSIDER initializing static fields inline rather than explicitly using static constructors, because the runtime is able to optimize the performance of types that don’t have an explicitly defined static constructor.
"Consider" in this context means to do so unless there's a good reason not to. In the case of static initializer fields, a good reason would be if initialization is too complex to be coded inline.
Being consistent is important, but this is the question to ask yourself:
"Do I have a constructor for anything else?"
Typically, I am creating models for data transfers that the class itself does nothing except work as housing for variables.
In these scenarios, I usually don't have any methods or constructors. It would feel silly to me to create a constructor for the exclusive purpose of initializing my lists, especially since I can initialize them in-line with the declaration.
So as many others have said, it depends on your usage. Keep it simple, and don't make anything extra that you don't have to.
Consider the situation where you have more than one constructor. Will the initialization be different for the different constructors? If they will be the same, then why repeat for each constructor? This is in line with kokos statement, but may not be related to parameters. Let's say, for example, you want to keep a flag which shows how the object was created. Then that flag would be initialized differently for different constructors regardless of the constructor parameters. On the other hand, if you repeat the same initialization for each constructor you leave the possibility that you (unintentionally) change the initialization parameter in some of the constructors but not in others. So, the basic concept here is that common code should have a common location and not be potentially repeated in different locations. So I would say always put it in the declaration until you have a specific situation where that no longer works for you.
There is a slight performance benefit to setting the value in the declaration. If you set it in the constructor it is actually being set twice (first to the default value, then reset in the ctor).
When you don't need some logic or error handling:
Initialize class fields at declaration
When you need some logic or error handling:
Initialize class fields in constructor
This works well when the initialization value is available and the
initialization can be put on one line. However, this form of
initialization has limitations because of its simplicity. If
initialization requires some logic (for example, error handling or a
for loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error
handling or other logic can be used.
From https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html .
I normally try the constructor to do nothing but getting the dependencies and initializing the related instance members with them. This will make you life easier if you want to unit test your classes.
If the value you are going to assign to an instance variable does not get influenced by any of the parameters you are going to pass to you constructor then assign it at declaration time.
Not a direct answer to your question about the best practice but an important and related refresher point is that in the case of a generic class definition, either leave it on compiler to initialize with default values or we have to use a special method to initialize fields to their default values (if that is absolute necessary for code readability).
class MyGeneric<T>
{
T data;
//T data = ""; // <-- ERROR
//T data = 0; // <-- ERROR
//T data = null; // <-- ERROR
public MyGeneric()
{
// All of the above errors would be errors here in constructor as well
}
}
And the special method to initialize a generic field to its default value is the following:
class MyGeneric<T>
{
T data = default(T);
public MyGeneric()
{
// The same method can be used here in constructor
}
}
"Prefer initialization in declaration", seems like a good general practice.
Here is an example which cannot be initialized in the declaration so it has to be done in the constructor.
"Error CS0236 A field initializer cannot reference the non-static field, method, or property"
class UserViewModel
{
// Cannot be set here
public ICommand UpdateCommad { get; private set; }
public UserViewModel()
{
UpdateCommad = new GenericCommand(Update_Method); // <== THIS WORKS
}
void Update_Method(object? parameter)
{
}
}

Proper Objective-C Helper "Wannabe" Private methods?

While I hate to beat a horse to death on this subject (I've read through various articles about this), but would just like to get more opinions on this matter before I create my "own convention" to use from now on while coding in Objective-C.
The convention that I want to figure out is ultimately how to (using best coding practices for production level code) use private methods in a class. Coming from a background in C#, when I write classes, usually there is a block of code that is repeated in multiple public methods (such as error checking, or WCF service connection setup). I usually create one block of this code and put it in a private method for only these public methods to access. This way if I need to make a change, I only need to do it in one spot, as opposed to 10 different places in a class, but then never giving users the ability to call this private method. For example:
public Class A
{
public void method1()
{
doErrorChecking()
// Do more stuff
}
public void method2()
{
doErrorChecking()
// Do more stuff
}
private doErrorChecking() { //Error Checking Code}
}
I understand that there is no real way to truly make that last method private in Objective-C, but just really want to make sure that when I create all future classes in Objective-C for iOS development I'm following the best practice available so future code refactoring on this matter won't be needed (hopefully). I've noticed people talking about categories, others just don't put the method in the #interface file, and others use extension methods. At the moment I'm just putting the method implementation in the #implementation file, but not the interface file. I'm also making the "wannabe" private method have a really distinct name so that sub-classing or overwriting methods is not an issue. Is this the path I should be following? Or for these particular scenarios is there a better way to do it?
Yes, it's perfectly reasonable to want to extract your functionality out into another method. The best way to do this in my opinion is using a class continuation, which you can put your private method declarations in. It can go above your #implementation block in your .m file, so it's not in the public header.
#interface MyClass ()
- (void)_privateMethod:(id)arg;
#end
The difference between a class continuation and a normal category (such as #interface MyClass (PrivateMethods)) is that the compiler will require you to implement the methods in your main #implementation block, rather than having a separate #implementation MyClass (PrivateMethods) block. This is arguably desirable when implementing helper methods like you described.
In terms of naming, it's relatively common to start private method names (and ivar names, for that matter) with an _, though not everyone does — apparently Apple reserves this for themselves, so you should pick a different prefix. The language doesn't enforce anything.
I would use a class extension, definitely. In the implementation file, include something like this above your #implementation:
#interface A ()
- (void) doErrorChecking;
#end
Then use the method in code as needed. Although due to objective-c's dynamic nature no method is truly private, this will obscure the method from your interface file while still technically including it in your own 'private' interface. In general, keep your .h file for methods and properties that are ok for public use, while limiting private use methods and properties to a class extension in the implementation file.
If you just need a reusable set of code that absolutely cannot be overridden by a subclass, you could just make a regular C function instead of a method. If the function is declared within the scope of the class #implementation block, it can still get access to all the private ivars of the object. You'd need to pass in a pointer to self, though, since a function isn't bound to a particular object
So it would look like this:
static BOOL isInValidState(MyClass *);
#implementation MyClass
static BOOL isInValidState(MyClass *self) {
if (self->somePrivateIvar == nil) {
return NO;
}
if ([self->someString isEqualToString:#"pigsAreFlying"]) {
return NO;
}
return YES;
}
- (void)method1 {
if (isInValidState(self) == NO) {
return;
}
// Do whatever method 1 does
}
- (void)method2 {
if (isInValidState(self) == NO) {
return;
}
// Do whatever method 2 does
}
#end
Since functions are not part of the method list of a class, this error checking method cannot ever be overridden. Since we declared it static, it is only accessible within the scope of this file, which means that it's effectively private; it cannot be called by an object of any other class.

Categories