✅ Class as a field?
Suppose I have Class1, Class2, and Class3. Class2 is just a container of information. At runtime I want Class1 to look into the contents of Class2, find Class3, and instantiate an instance of Class3.
For this, I DO NOT WANT class2 to have an instance of class3, and I do not want class2 to have any code/knowledge of what class3 is going to do. In theory, I want Class2 to have a field which gives a type that implements a specified interface that allows Class1 to call it.
Is there a way to do this?
53 Replies
wouldn’t that require the class to hold an instance of the type with the interface?
well, the goal is for class2 to be immutable. So it should only be able to tell Class1 that it needs to instantiate a Class3
as there could be a Class4/5/6 also that all implement the same interface. And different instances of class2 would refer to different classes, if that makes sense
I’m not sure how that would work
class2 could have a method to output a reference to a new instance of class3/4/5, but the point still stands that class2 needs to be able to hold information of what class3/4/5 are without an instance
I kept it a bit more generic, allowing for a non-generic Class2
i see. This might be out of scope, but I’m trying to make this in an asset file in unity as a scriptableobject. The idea is for Class2 instances to mostly exist as files which are never modified during runtime.
And a generic would require me to instantiate a new Class2 at runtime, which is not desirable. Sorry that I didn’t make that clear.
It's definitely still not clear lol
How could you possibly modify a file during runtime
ScriptableObject instances are stored in files. Class2 : ScriptableObject, and I want instances of Class2 to never be modified or instantiated at runtime.
If I have Class2<T>, then some code needs to have knowledge of Class2’s connection to class3, and I would need to instantiate Class2 as a generic.
If they shouldn't get instantiated at runtime, then what purpose do they serve
So something would need to make new Class2<Class3>. But also, if I had something with knowledge that class3 is supposed to be linked to that specific instance of Class2, then I would be done.
Just delete the class lol
Class2 contains data for TileObjects in a game. Things like sprite, gamelogic, tilelayer, name, etc.
Class2 describes the data. Class2 instances are files with those fields filled out for a specific type of tile.
Now we're getting somewhere
Class2 only needs to store knowledge that it has a link to Class3.
class2 does not store an instance of class3. It just needs to be able to articulate to another class (class1) to go instantiate a class3 and call code from it.
So if class1 asks: I’m looking for the ITileScript associated with you. Class2 can respond: That would be Class3:ITileScript. Or Class4:ITileScript…
I hope that makes it more clear
yes?
is GroundDescriptor the Class2 here?
I would say so
that makes sense, but I can’t really serialize that
How so?
well, Class2 is like TileData. If I want to do this, then I would need to make an interface and child class for every different type of tile, just to be able to make an instance that is a child of TileData
so I could have a file of the child, which has the generic part filled out explicitly
You need to explain what you mean by "file"
You keep saying that and I don't know what it refers to
i can copy, move, delete it on my hard drive
i could drag it to a different folder and all that. a literal file
I don't understand how a file corresponds to a c# class
Class2 describes the rules for writing and parsing the contents of the file, as though it is an instance of class2
So if I do:
public class Class2: ScriptableObject { int i; }.
Now I can make files, like
Number2.Asset, which corresponds to an instance of class2 with int i, and is accessible as such.
And I can make Number5.Asset, which encodes another instance which just has i =5.
Incomprehensible lmfao
Then Unity just lets you read that at runtime, so you can pass in the file as an instance of the class
so I can drag Number2.asset and Number5.asset, to a script that takes two Class2, and then that script can read the values and do stuff with them
this is getting outside of the scope of the original question
I mean I think it's necessary to explain this to even comprehend what's going on
ultimately, I would like to store a class as a field. Not an instance of a class, but information that can be read to point to a specific class.
So i can have a class2 with a property that returns the type of that class3/4/5
You also choose to abstract away a lot of info. I think in this case it would be better if you just gave a complete example and your goal API
When a tile collision happens, TileHandler looks into an instance of TileData:ScriptableObject associated with that collision. TileHandler wants to get a type that implements ITileScript associated with TileData. ITileScript has a method that (when implemented) is supposed to do something specific for that tile.
TileHandler calls ActivateCollidedTile, which is a function in ITileScript.
Then I can have something like:
GroundScript :ITileScript, SpringScript:ITileScript…
Then TileData GroundData contains a field that tells TileHandler that the ITileScript associated with it is GroundScript.
Can you just post the code in a condensed form
This is impossible to understand for me
i just want to store an object of type Type in my class T.T
as a field
no generics
instances cannot be created or altered during runtime
There wouldn't be any altering at runtime just because you use generics
What you're asking is just nonsensical is all
to have a field of type Type?
Yes, it sounds like very bad practice
I can't tell if it's a proper solution because what you've explained doesn't make sense to me
why would that be nonsensical
specifically, a field of type Type with the restriction that the Type in the field implements a particular interface
That must involve generics
You can't constrain anything without generics
So then please. Ask your question once again, without trying to abstract anything away, with as much detail as possible, and the complete architecture, as well as the goal API you want to see.
You can skip including any unnecessary members obviously
Class1 gets an instance of Class2. Class2 instances need knowledge of a specific class implementing a common interface (ITileScript). Class1 looks into an instance of Class2 to know what class that is, and calls a method guaranteed in the interface implementation
Why are you writing it out in words
Please just post code
i can’t post code that doesn’t exist
sounds here like you have plenty of code
i have none of the code relevant to this discussion
So you're solving a non-existent problem...?
I am not going to code an interface and class that cannot be accessed
that’s basically where I’m at
I don't understand anything lmfao
no idea, but probably not without great difficulty
or learning something that would let me do that
I could maybe store a string that gets parsed to a class, but spelling issues and slow lookup etc…. it’s way too unsafe
i’m working in unity lol
but any string => code conversion is always unsafe
I mean just because you're in unity doesn't mean you have to use bad architecture
i’m trying to refuse to use a string to call a class name. That is really a separate issue from trying to store a field of type Type
well I would rather have a Type that needs to implement an interface
what I’m trying to convey is storing information about a type and not holding an instance
So for this, why did a generic argument constrained to an interface not work?
That seems like the perfect solution
Because unity serialization, mostly
i gtg back to work. I’ll keep thinking about it tho
What's serialization in unity exactly? You wouldn't need to serialize this tile info would you?
So then what's wrong with this?
I don't think this should have any issues with serialization?
I found a solution. There’s a package called ClassTypeReferences which makes a serializable reference to a class type.
If I’m understanding this correctly, why not just serialize an enum and make a factory method to generate the class based on the value of the Enum?
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.