• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Existingman · Nov 01, 2014 at 11:43 AM · c#dictionarytypemultidimensional array

3 dimensional Dictionary that returns Types

This is kind of 2 questions in one. First of all, can you instantiate an object of a type that is returned from a method? So something like: BaseClass myObject = new findObjectType(parameter1, parameter2, parameter3)();

And secondly, what would be the best way to store the Types on the basis of 3 enums/ints? A list of lists of lists? or dictionaries? or Arrays? or is there a better way?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Nov 02, 2014 at 04:34 AM

Yes, it is possible, but not the way you described it in your question. First of all "a type" like "GameObject" for example is just the name of a type that is recognised by the compiler to identify that type. It's not possible to "store" a reference to such a "name" in a variable because that name doesn't have an actual type. The compiler statically links the correct type with the "new" operator. Therefore you can't use "new" with a variable.

You might say: wait, there are generics. Yes, but generic parameters are nothing like variables. They are actually like alias names or placeholders for the type you insert when you use a generic class / method. Generic types allows you to replace such a fix-wired type at runtime with a concrete type. Since there's no variable "type" to store that information, it doesn't work that way. The solution is the System.Type class.

The System.Type class is part of the reflection system. It is used to describe other types. For every type there is exactly one System.Type object instance that describes that type. Even the System.Type class itself has an instance of System.Type that describes itself. The Type class contains properties which tell you if that type is a generic type, an array type, a class, a struct, an interface, (...). It also has methods to enumerate the members of that type and allows you to inspect them. In C# the "typeof" operator returns the System.Type instance for a given type. This: typeof(GameObject) would return the System.Type object that describes the GameObject class. In UnityScript there is no typeof operator but UnityScript automatically / implicitly converts a type into it's System.Type object based on the usage.

The Unity API uses the System.Type type quite a lot. The non generic version of AddComponent for example takes a System.Type object to add that class described by the instance to the gameObject. The generic and the string version simply use the System.Type version in the end.

Since the System.Type class is an ordinary class, you can put references to instances of that class into a List or an array without any problems. However as said earlier you can't use the new operator with variables. The usual way using reflection to create an instance of a class described by a Type object is quite cumbersome as you would have to iterate through the available constructor methods, pick the one that suits your needs and call it via reflection. However the reflection system provides a class that simplifies the creation of a class. It's called Activator

The Activator class provides a static method CreateInstance which takes a System.Type reference and will create and return a new instance of the described type. It will simply call the default constructor if one is available. There are also a couple of overloads which allows you to use private constructors or to additionally pass a list of parameters. CreateInstance will try to find a constructor that matches your parameter list.

Here's an example using a 3 dimensional array to store System.Type objects and how to create an instance of one of those types:

 System.Type[,,] types = new System.Type[3,4,5];
 // you have to initialize your array somehow:
 types[0,0,3] = typeof(SomeClassDerivedFromBaseClass);
 types[0,0,4] = typeof(SomeOtherClassDerivedFromBaseClass);
 //[ ... ]
 
 BaseClass CreateInstance(int i1, int i2, int i3)
 {
     return (BaseClass)System.Activator.CreateInstance(types[i1,i2,i3]);
 }

Note: The reflection system always work with System.Objects. So the reference that CreateInstance return is always of type System.Object. In my example i simply cast it to our BaseClass type. This cast will of course fail and throw an exception if you put a type in that types array that is not derived from BaseClass. You can also use refection to get all types that are derived from a certain base class.

As final note i should mention that reflection is not the usual way to work with classes and objects. Reflection actually breaks almost all OOP rules and is in most cases way slower than using the normal statically typed way. However in some cases it's difficult or impossible to get the same results with pure OOP. Using the factory pattern as Unitraxx suggested is quite verbose and requires much more work to implement, but it's more type-safe and usually faster at runtime.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Unitraxx · Nov 01, 2014 at 12:38 PM

For your first question:

 BaseClass myObject = createObject(parameter1, parameter2, parameter3);

and createObject would simply return new SubClassX() based on your parameters. (You can do some internet searches on [abstract] factory pattern if you want the best way to organize this.)

For the second question it's better to give some more information as I find it really weird that your only viable solution is to create classes based on 3 numbers, but still this can easily be accomplished with the factory pattern.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

28 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Accessing a Class's Variables from within a Dictionary Element 1 Answer

Name GUI input help in C# 0 Answers

Dictionary reference disappearing 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges