Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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
1
Question by Hyperion · Jun 05, 2014 at 02:43 AM · c#switchvalueconstantstatement

C# switch: A constant value is expected

Hi everyone,

I have a large switch statement in my question and answer program that has "error CS0150: A constant value is expected." I researched this type of problem and it pertains mostly to typeOf switches, but my cases seem different. Here is an example of one of my cases:

 case C_Jarvis.C_myString.ToLower().Contains("good") && C_Jarvis.C_myString.ToLower().Contains("how") && C_Jarvis.C_myString.ToLower().Contains("you?"):
                 Q1I1=true;
                 Debug.Log("Q1I1 true");
                 break;

Also, the JavaScript counterpart that I developed earlier as a prototype worked perfectly, and without errors; exactly how I wanted it to work.

Please help me understand why this error is appearing and possibly how to fix it. In more detail, this is a database that defines its questions and answers. Unless I absolutely have to, I do not want to use if statements, as this database will in the future contain hundreds of such cases and I do not want to clutter the script with hundreds of ifs.

I appreciate your help!

-Hyperion

Comment
Add comment · Show 6
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 Hyperion · Jun 05, 2014 at 02:49 AM 0
Share

Also, according to http://msdn.microsoft.com/en-us/library/6weteh5e%28v=vs.90%29.aspx the case must be a non-variable case in order to prevent the problem. So variable cases in JavaScript are viable but not in C#?

avatar image Owen-Reynolds · Jun 05, 2014 at 01:21 PM 2
Share

For hundreds of these, worth it to learn the good way:

Write a small class which holds lists of words. For the example above, just ["good", "how", "you"]. There might also be a var for a "mustStartWith" word, or "must not have" words ... . Put all 100 cases in a list of these. Then have a loop scan the list vs. your phrase.

Even if you do go with ifs, run ConvertToLower only 1 time! w=myString.ToLower(); if(w.Contains...

avatar image Hyperion · Jun 05, 2014 at 09:24 PM 0
Share

I see, thanks for the insight.

avatar image Hyperion · Jun 06, 2014 at 09:04 PM 0
Share

@Owen_Reynolds As an initial step, I did void Start(){ string s = C_Jarvis.C_myString.ToLower(); }

and then did s.Contains(...)etc... But now the program is not doing anything. Is the problem in the variable type?

avatar image Owen-Reynolds · Jun 06, 2014 at 09:26 PM 1
Share

The idea is, each time you get a new C_Jarvis, could create a lower-case version. So can't do it in Start, since it only happens once, and C_Jarvis doesn't even have a value.

But, it seems you don't have a lot of program$$anonymous$$g experience. The worst thing you can do is take a bunch of fancy advice from different people (including me.) Stick to things that work for you, and the fancy stuff will come later.

Show more comments

3 Replies

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

Answer by SirCrazyNugget · Jun 05, 2014 at 03:49 AM

Unfortunately, that's not possible in C# due to the way it pre-compiles the code and requires constants, it can do multiple cases or numerical calculations but those won't help you.

Why not throw all possibilities into a list or multidimensional array and run through each possibility, it could start effecting performance with so many string operations so use some sort methods like most possible answer or just alphabetical sorts and give it a hand in where to start searching.

If you want to avoid using so many if and if else use a while and use a function which handles the comparisons for you. Depending on the number of possibilities you'll want to either favour using a predetermined list (higher on memory) or on-the-fly searches (higher on CPU).

 void Start(){
         string C_Jarvis_etc = "Good how are you?";
         CaseContains(C_Jarvis_etc, new string[]{"bad", "times"});
         CaseContains(C_Jarvis_etc, new string[]{"good", "how", "you"});
     }
 
     bool CaseContains(string str, string[] inStrs){
 
         string lowerStr = str.ToLower();
         foreach (string s in inStrs){
             if(!lowerStr.Contains (s)){
                 Debug.Log (str + " didn't contain: " + s);
                 return false;
             }
         }
         Debug.Log (str + " contained everything!");
         return true;
     }

If you plan on using the list then go for something like:

 void Start(){

     lstCmps = new List<string[]>();
     lstCmps.Add (new string[]{"bad", "times"});
     lstCmps.Add (new string[]{"good", "how", "you?"});
     lstCmps.Add (new string[]{"stopped", "looking"});

     Debug.Log (C_Jarvis_Contains ("Good how are you?"));
     Debug.Log (C_Jarvis_Contains ("Have you stopped looking"));
     Debug.Log (C_Jarvis_Contains ("You won't find this"));
 }

 int C_Jarvis_Contains(string str){

     for(int i = 0; i < lstCmps.Count; i++){
         if(CaseContains (str, lstCmps[i])){
             return i;
         }
     }
     return -1;
 }

 bool CaseContains(string str, string[] inStrs){

     string lowerStr = str.ToLower();
     foreach (string s in inStrs){
         if(!lowerStr.Contains (s)){
             return false;
         }
     }
     return true;
 }

The latter way you can perform a switch on the integer returned if you really need to use a switch statement.

Comment
Add comment · Show 3 · 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 Hyperion · Jun 05, 2014 at 05:31 PM 0
Share

Thank you! Would you know a link where I can find most of the string operations in your code, so that I can understand it better? (I am not too experienced in calling information from strings and creating info from them...)

avatar image SirCrazyNugget · Jun 05, 2014 at 06:22 PM 0
Share

$$anonymous$$ost are custom functions but I'll go through most variables/functions with a little bit more insight First example

 //entry point for the script
 void Start(){
     
     //variable for the users input
     string C_Jarvis_etc = "Good how are you?";
     
     //two tests which will require if comparisons
     CaseContains(C_Jarvis_etc, new string[]{"bad", "times"});
     CaseContains(C_Jarvis_etc, new string[]{"good", "how", "you"});
     
     //third test which acts on result
     if(CaseContains(C_Jarvis_etc, new string[]{"Good", "you?"})){
         Debug.Log ("Did contain 'Good' 'you'");
         //do something extra
         
     }
 }
  
 //function to evaluate if all inStrs appear in str
 //returns true or false
 bool CaseContains(string str, string[] inStrs){
  
     //converts and temporarily stores string str to lowercase
     //try to $$anonymous$$imise the number of times you perform any string operation
     string lowerStr = str.ToLower();
     
     //iterates through each of the strings in the inStrs array
     //and returns false if it isn't contained
     foreach (string s in inStrs){
         
         //if !lowerStr.Contains(s) is the same as
         //if lowerStr.Contains(s) == false
         //as all words must be found when one doesn't exist function exits
         if(!lowerStr.Contains (s)){
             Debug.Log (str + " didn't contain: " + s);
             return false;
         }
     }
     
     //as all strings have been found return true
     Debug.Log (str + " contained everything!");
     return true;
 }

Second example List lstCmps;

 //entry point for the script
 void Start(){
 
     //create a list for all possible comparisons
     lstCmps = new List<string[]>();
     
     //populate the list
     lstCmps.Add (new string[]{"bad", "times"});
     lstCmps.Add (new string[]{"good", "how", "you?"});
     lstCmps.Add (new string[]{"stopped", "looking"});
     
     //three test user inputs to analyse
     Debug.Log (C_Jarvis_Contains ("Good how are you?"));
     Debug.Log (C_Jarvis_Contains ("Have you stopped looking"));
     Debug.Log (C_Jarvis_Contains ("You won't find this"));
 }

 //returns an integer of the index which contained the string str

int C_Jarvis_Contains(string str){

     //iterates through predefined list of options
     //returns index when all required strings are found
     for(int i = 0; i < lstCmps.Count; i++){
         if(CaseContains (str, lstCmps[i])){
             return i;
         }
     }
     
     //returns -1 when string isn't found
     return -1;

}

 //function to evaluate if all inStrs appear in str
 //returns true or false

bool CaseContains(string str, string[] inStrs){

     //converts and temporarily stores string str to lowercase
     string lowerStr = str.ToLower();
     
     //iterates through each of the strings in the inStrs array
     //and returns false if it isn't contained
     foreach (string s in inStrs){
         
         //if !lowerStr.Contains(s) is the same as
         //if lowerStr.Contains(s) == false
         if(!lowerStr.Contains (s)){
             return false;
         }
     }
     
     //as all strings have been found return true
     return true;

}

avatar image Hyperion · Jun 05, 2014 at 09:21 PM 1
Share

Thank you. Now I can use this code more intellectually.

avatar image
1

Answer by rutter · Jun 05, 2014 at 02:56 AM

If you want to use a switch in C#, your cases must be constant expressions that can be fully resolved at compile time.

New programmers tend to assume that switches are internally implemented by a series of if-then-else branches. That's not as true as you might guess. In C#, they're implemented by highly optimized jump tables that are fully resolved ahead of time by the compiler; if the compiler doesn't know your case values, it can't do any of that.

If you really do need to use a variable expression, just use if statements.

So, sorry, but there's no way to do that. Not how the language or the feature were designed. The good news is that easy workarounds are available.

Comment
Add comment · Show 1 · 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 Hyperion · Jun 05, 2014 at 03:11 AM 0
Share

Alright, thanks. That's what I assumed but I was hoping that there was a more comfortable solution.

avatar image
0

Answer by frankiboss · Jul 10, 2014 at 10:55 AM

This works, only need to cast the variable and put the enum in order.

public enum Estados{ BLIND, DEAD }

//BLIND = 0 and DEAD = 1 and keep going

switch ((int)estado){

     case 0:
         Debug.Log ("Estado: " + estado);
         
             break;
     case 1:
         Debug.Log ("Estado: " + estado);
         
         break;
     case 2:
         Debug.Log ("Estado: " + estado);
             
         break;
     case 3:
         Debug.Log ("Estado: " + estado);
         
         break;
     case 4:
         Debug.Log ("Estado: " + estado);
         
         break;
     }
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.

Follow this Question

Answers Answers and Comments

24 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

What is wrong with my c# switch statement? 1 Answer

Variable value not changing (bug or i'm just an idiot?) 0 Answers

Save Values On Closing of Game 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