C
C#2y ago
OkashiKami

❔ Unity3D C-Sharp Create class instance from Type

Hello need a little help trying to create an instance of a type at run time but once I try to create the instance it gets returned null, even after verifying that the time I'm looking for is correct but the System.Activator is not working for me I event tried to use the Assembly
35 Replies
OkashiKami
OkashiKamiOP2y ago
The function that does the conversion
public static IEnumerable<object> GetClasses(Type type, string _namespace = null, Predicate<Type> predicate = null)
{
var assembly = type.Assembly;
var results = new List<Type>();
IEnumerable<Type> types = assembly.GetTypes();
if (!string.IsNullOrEmpty(_namespace))
results.AddRange(types.Where(x => string.Equals(type.Namespace, _namespace, StringComparison.Ordinal)));
results = results.Where(x => Equals(x.BaseType, type)).ToList();
if (predicate != null)
results = results.Where(t => predicate(t)).ToList();

var classes = new List<object>();
foreach (var result in results)
{
try
{
var name = result.FullName;
var _class = Activator.CreateInstance(result, BindingFlags.Public);
if (_class != null)
classes.Add(_class);
}
catch(Exception ex)
{
Debug.LogException(ex);
}
}

return classes;
}
public static IEnumerable<object> GetClasses(Type type, string _namespace = null, Predicate<Type> predicate = null)
{
var assembly = type.Assembly;
var results = new List<Type>();
IEnumerable<Type> types = assembly.GetTypes();
if (!string.IsNullOrEmpty(_namespace))
results.AddRange(types.Where(x => string.Equals(type.Namespace, _namespace, StringComparison.Ordinal)));
results = results.Where(x => Equals(x.BaseType, type)).ToList();
if (predicate != null)
results = results.Where(t => predicate(t)).ToList();

var classes = new List<object>();
foreach (var result in results)
{
try
{
var name = result.FullName;
var _class = Activator.CreateInstance(result, BindingFlags.Public);
if (_class != null)
classes.Add(_class);
}
catch(Exception ex)
{
Debug.LogException(ex);
}
}

return classes;
}
OkashiKami
OkashiKamiOP2y ago
original Class
OkashiKami
OkashiKamiOP2y ago
The method that calls the function
var classes = Utilities.GetClasses(typeof(Modifier), "OkashiKami.Terragen.Modifiers").ToList();
foreach (var _class in classes)
{
var name = _class.ToString().Split('.').Last();
if (name.Equals(nameof(ChunckModifier)))
{
if (self.me.modifiers.Find(x => x.GetType().Equals(typeof(ChunckModifier))) != null)
{
menu.AddDisabledItem(new GUIContent(name));
continue;
}
}

menu.AddItem(new GUIContent(name), false, ProcessDropDownButtonClick, _class);
}
var classes = Utilities.GetClasses(typeof(Modifier), "OkashiKami.Terragen.Modifiers").ToList();
foreach (var _class in classes)
{
var name = _class.ToString().Split('.').Last();
if (name.Equals(nameof(ChunckModifier)))
{
if (self.me.modifiers.Find(x => x.GetType().Equals(typeof(ChunckModifier))) != null)
{
menu.AddDisabledItem(new GUIContent(name));
continue;
}
}

menu.AddItem(new GUIContent(name), false, ProcessDropDownButtonClick, _class);
}
mikernet
mikernet2y ago
Activator.CreateInstance does not return null (unless the type is Nullable<Something>) so something about how you are debugging things is not right. I'm not going to read through all that code but if you're saying that Activator.CreateInstance is returning null then I have my doubts about how you're testing this
OkashiKami
OkashiKamiOP2y ago
i event stepped through the code and everything is correct up to the section of the fist codebase right after var classes = new List<object>(); everything after that fails
mikernet
mikernet2y ago
everything after that fails
You need to be more specific about what that means Program crashes? You get an exception? You get a null when you don't expect a null?
OkashiKami
OkashiKamiOP2y ago
while stepping as soon as i get to the section that says Activator.createInstance it return null like i said not really sure i'm getting a MissingMethodException: Constructor on type 'OkashiKami.Terragen.Modifiers.SmoothModifier' not found. exception but all my classes have a default constructor in them so i really don't understand
mikernet
mikernet2y ago
Um
OkashiKami
OkashiKamiOP2y ago
and i expect when i rand the Activator.CI to return an object of the type that was provided but instead i get a null value when after inspecting the elements with breakpoints all is good but not that part
mikernet
mikernet2y ago
Well if its throwing an exception then its not returning anything, including null, its throwing an exception That said...idk, it looks like you have a public default ctor So that doesnt make sense
OkashiKami
OkashiKamiOP2y ago
yes true one thing i did notice is that the exception doesn't get fired unless i put it in a try catch otherwise it doesn't do anything
mikernet
mikernet2y ago
You must have something weird going on because activator.createinstance has never had any problems afaik
OkashiKami
OkashiKamiOP2y ago
do you thing it's because those classes inherits a base class in my case Modifier.cs
mikernet
mikernet2y ago
No There is no overload of CreateInstance that takes 2 params with a second BindingFlags parameter So idk what overload that is calling But very likely not the right one Remove the binding flags parameter It's probably looking for a ctor that takes a BindingFlags parameter to pass that into Because it thinks youre trying to specify that as a ctor argument
mikernet
mikernet2y ago
Activator.CreateInstance Method (System)
Creates an instance of the specified type using the constructor that best matches the specified parameters.
OkashiKami
OkashiKamiOP2y ago
so you know how on msdn they have CreateInstance(String, String) Creates an instance of the type whose name is specified, using the named assembly and parameterless constructor. for some reason that one is not available to me
mikernet
mikernet2y ago
Forget that You have a type All you need to do is call CreateInstance(type) Theres no reason for you to be using strings
OkashiKami
OkashiKamiOP2y ago
this is my Activator class looks like
mikernet
mikernet2y ago
Yes, and what I said stands
OkashiKami
OkashiKamiOP2y ago
let me try with just type
OkashiKami
OkashiKamiOP2y ago
here me stepping through the code
OkashiKami
OkashiKamiOP2y ago
i even show elements as we are stepping
mikernet
mikernet2y ago
It's not null If it was then it wouldnt be added to the list That 'null' value is something different
mikernet
mikernet2y ago
It's showing you properties on the object that are set:
OkashiKami
OkashiKamiOP2y ago
yeah it seams like it's creating and instance of the base class not the actual class of the type but what it inherits from
mikernet
mikernet2y ago
The 'null' is what ToString() is returning Which is probably coming from some base class I dont see a ToString() override on your classes so its probably coming from UnityObject Sorry UnityEngine.Object
mikernet
mikernet2y ago
OkashiKami
OkashiKamiOP2y ago
ah probably
mikernet
mikernet2y ago
Override ToString() on Modifier and return GetType().FullName And you'll see it'll show the class name Instead of 'null' The activation of the types is working fine
OkashiKami
OkashiKamiOP2y ago
your right ugh dam are you serious rn
mikernet
mikernet2y ago
🙂 Gotta love debugging rabbit holes 😛 We all get stuck in them sometimes
OkashiKami
OkashiKamiOP2y ago
i would of never guess thank you so much for your help very much appreciate it dam much love
Shirasho
Shirasho2y ago
I've always wondered about that. 👍 The nullable type annotation never made sense.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server