WithErrorCode() and WithMessage() accepts strings, so you can just set simple string variables with the applicable details and pass the variable.
string myerror = "666";
string mymessage = "My Custom message";
RuleFor(person => myclass.Property1).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
RuleFor(person => myclass.Property2).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
RuleFor(person => myclass.Property3).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
RuleFor(person => myclass.Property4).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
You should consider if this make sense however, the purpose of validation is to enhance debugging the problem with the data, so the messages and error codes should be as specific as possible. This might be OK in your case, only you can judge this.
Edit: To answer your question below.
Fluent Validation offers two other methods which might be useful.
I think the dependencies is more what you are looking for. So then you can have something like this;
RuleFor(person => myclass.Property1).NotNull().DependentRules(() => {
RuleFor(person => myclass.Property2).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
RuleFor(person => myclass.Property3).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
RuleFor(person => myclass.Property4).NotNull().WithErrorCode(myerror).WithMessage(mymessage);
}).WithErrorCode(myerror).WithMessage(mymessage);
And you can embed rule within rule, with rule etc. But this quickly becomes difficult to read and terrible to debug.