Другой способ добиться этого, чтобы иметь P1 ссылочный P2 в качестве проекта решения, но имеют ссылочный P2 P1 только его выходной DLL или EXE.
Вы теряете проверку кросс-проекта/зависимостей, но это позволяет вам перекрестно ссылаться.
Я должен был сделать это с помощью долговременного приложения WinForms, которое изначально было написано на VB, но через несколько лет перешло на C#. Все новые Windows Forms были написаны на C#, который не мог быть тем же проектом, что и формы VB, но некоторые формы VB, необходимые для вызова новых форм C# и Vice verca.
EDIT 1
Одним из недостатков является то, что, если P2 ссылается P1, как это проект вывода DLL/EXE, а затем, когда вы очищаете/восстановить решение, там ошибка, вы находитесь в положении, в котором вывод DLL/EXE больше не существует и не может быть воссоздан до устранения ошибки, но решение больше не может быть построено, так как у него отсутствует ссылка.Нехорошее место быть, поэтому не забудьте периодически копировать свою выходную DLL/EXE, чтобы вы могли выйти из этого, если это когда-нибудь случится.
Вы не можете просто создать ссылку, вы правы. Там _might_ будет способом использования отражения или чего-то другого, но разумным способом является просто переместить общую логику в третий проект P3 и ссылку P3 из P1 и P2. –