Alternative to calling a virtual method in C #

I use NHibernate for my C # projects, and therefore I have several model classes.

Let's look at the following example:

using System;

namespace TestProject.Model
{
    public class Room
    {
        public virtual int Id { get; set; }
        public virtual string UniqueID { get; set; }
        public virtual int RoomID { get; set; }
        public virtual float Area { get; set; }

    }
}

Comparison of these objects with NHibernate has been discontinued. Now I want to create a new Room object, and I want to save it to the database. To avoid setting each element separately, I add a new constructor to the model class. Below virtual members I write:

public RoomProperty()
{

}


public RoomProperty(int pRoomId, int pArea)
{
        UniqueID = Guid.NewGuid().ToString();
        RoomID = pRoomId;
        Area = pArea;
}

Parsing my code with FxCop tells me the following:

"ConstructorShouldNotCallVirtualMethodsRule"
This rule warns the developer if any virtual methods are called in the constructor of a non-sealed type. The problem is that if a derived class overrides the method then that method will be called before the derived constructor has had a chance to run. This makes the code quite fragile. 

This page also describes why this is wrong, and I also understand this. But I'm not sure how to solve the problem.

When I remove all the constructors and add the following method ...

public void SetRoomPropertyData(int pRoomId, int pArea)
        {
            UniqueID = Guid.NewGuid().ToString();
            RoomID = pRoomId;
            Area = pArea;

        }

.... , , , NHibernate . :

NHibernate.InvalidProxyTypeException: The following types may not be used as proxies:
VITRIcadHelper.Model.RoomProperty: method SetRoomPropertyData should be 'public/protected virtual' or 'protected internal virtual'

, . ()?

+5
3

. . overriden set , , .

, - - overriden set, . .

, .

. , .

+4

, :

  • (, NHibernate ).
  • , , .
  • Create, , .

: , №3 .

public class Room
{
    public virtual int Id { get; set; }
    public virtual string UniqueID { get; set; }
    public virtual int RoomID { get; set; }
    public virtual float Area { get; set; }

    public static Room Create(int roomId, int area)
    {
        Room room = new Room();
        room.UniqueID = Guid.NewGuid().ToString();
        room.RoomID = roomId;
        room.Area = area;
        return room;
    }
}
+1

IMHO, a good idea is to make the base class - abstract and its constructor - protected . Then, the inherited classes have their own private constructor and - for the outside world - a single static method, such as "Instance", which first initializes the constructor, then - calls the entire set of class methods in the correct sequence and finally - returns an instance of the class.

0
source

All Articles