TL; DR: 1) Версия моего кода, отличная от c, позволяет мне преобразовать объект в интерфейс, который, как я знаю, он реализует; версия generi c, в которой я привожу к типу generi c, не компилируется. Мне не хватает ограничения и / или обходного пути? 2) Если C# не поддерживает то, что я делаю, есть ли другой способ достичь sh моей более широкой цели?
Самое близкое, что я подошел к поиску проблемы, похожей на мою, - это , где единственным ответом было «Это не имеет смысла, поскольку не приводит [sic] к каким-либо ограничениям». Итак, позвольте мне указать точное ограничение, с которым я сталкиваюсь ...
Вот не-общая c версия моего кода; Надеюсь, встроенные комментарии объяснят, что я пытаюсь сделать и почему:
public interface ISomeInterface
{
string SomeFxn();
}
[Serializable]
public class SerializableInterfaceReferenceForUnity
{
// Unity has long been able to serialize references to its own objects, but using this
// attribute on a "raw C#" object (i.e., anything other than Object) would try to
// serialize the **value**.
[SerializeField] private UnityEngine.Object unityObj;
// This new(-ish) attribute actually allows us to serialize references ... but ONLY to
// "raw C#" objects! (If rawObj is a UnityEngine.Object that implements
// ISomeInterface, I get error messages in the console.)
[SerializeReference] private ISomeInterface rawObj;
// So, a kludge: branching my logic based on the type that implements ISomeInterface.
[SerializeField] private bool objIsUnityType;
// In my defense, I *think* the kludge will be entirely hidden on the back-end;
// the API will "just work":
public ISomeInterface obj
{
get
{
// FLAG: this next line works here, but breaks in generic version
if (objIsUnityType) { return (ISomeInterface) unityObj; }
else { return rawObj; }
}
set
{
switch (value)
{
case UnityEngine.Object uo:
{
objIsUnityType = true;
unityObj = uo;
rawObj = null;
return;
}
default:
{
objIsUnityType = false;
rawObj = value;
unityObj = null;
return;
}
}
}
}
}
Все вышеизложенное хорошо, но настоящая цель - позволить мне сериализовать ЛЮБОЙ интерфейс в Unity. Итак, вот общая версия c ... которая является той же строкой, за исключением того, что ISomeInterface
становится TSomeInterface
:
[Serializable]
public class SerializableInterfaceReferenceForUnity<TSomeInterface>
// where TSomeInterface : { what goes here?! }
{
[SerializeField] private UnityEngine.Object unityObj;
[SerializeReference] private TSomeInterface rawObj;
[SerializeField] private bool objIsUnityType;
public TSomeInterface obj
{
get
{
//"CS0030 Cannot covert type 'UnityEngine.Object'
// to 'TSomeInterface'" on the below:
if (objIsUnityType) { return (TSomeInterface) unityObj; }
else { return rawObj; }
}
set
{
switch (value)
{
case UnityEngine.Object uo:
{
objIsUnityType = true;
unityObj = uo;
rawObj = default;
return;
}
default:
{
objIsUnityType = false;
rawObj = value;
unityObj = null;
return;
}
}
}
}
}
Я скрещиваю пальцы, все, что мне нужно, это ограничение на тип generi c.
За исключением этого, есть ли какое-либо обходное решение (скажем, какое-то отражение c) для изменения произвольного объекта на тип интерфейса (generi c) ?
За исключением ЭТОГО, есть ли способ достичь sh той же цели (а именно, сериализации Unity ссылок на объекты, реализующие данный интерфейс, независимо от того, являются ли эти объекты встроенными в Unity или сырые C#) чистым способом?
Также приветствуются отзывы / тухлые помидоры относительно моего кладжа.