Return object(T) from switch statement

javascript switch vs object performance
javascript switch multiple case
javascript switch return
javascript switch statement
expression in switch case
es6 switch case
how to call a function in switch case in javascript
switch statement comparison operators

In my code I am having ManagerService of T type which can be BaseManager or AnotherManager:

abstract class BaseManager { }
abstract class FooManager : BaseManager { }
abstract class AnotherManager : BaseManager { }
class ManagerService<T> where T : BaseManager { }

Now I want to get specific object by string:

static ManagerService<T> GetService<T>(string serviceName)  where T : BaseManager
{
    switch(serviceName)
    {
        case "foo": return new ManagerService<FooManager>();
        case "another": return new ManagerService<AnotherManager>();
    }
    throw new ArgumentException("Service not found");
}

And here would be usage:

static void Main(string[] args)
{
    var serviceBase = GetService("foo"); // it should return ManagerService<FooManager>
    var serviceAnother = GetService("another"); // it should return ManagerService<AnotherManager>
}

Unfortunately that doesnt work. I am having error:

Cannot implicitly convert type 'app.ManagerService<app.FooManager>' to 'app.ManagerService<T>'.

What is wrong there?

When calling GetService<T>(string serviceName), the generic type T must be known at compile time. Either you need to specify it when making the call, or the compiler must be able to derive it from the parameters of the method (but you have no such parameters).

You can fix that by eliminating serviceName and using T instead, like this:

static ManagerService<T> GetService<T>() where T : BaseManager
{
    return new ManagerService<T>();
}

static void Main(string[] args)
{
    var s1 = GetService<FooManager>();     // returns ManagerService<FooManager>
    var s2 = GetService<AnotherManager>(); // returns ManagerService<AnotherManager>
}

If you don't know the T-s in advance (you only know serviceName at runtime) then you can use the abstract base type BaseManager:

abstract class ManagerService { }
class ManagerService<T> : ManagerService where T : BaseManager { }

static ManagerService GetService(string serviceName)
{
    switch(serviceName)
    {
        case "foo":
            return new ManagerService<FooManager>();
        case "another":
            return new ManagerService<AnotherManager>();
    }
    throw new ArgumentException("Service not found");
}

static void Main(string[] args)
{
    var s1 = GetService("foo");     // returns ManagerService<FooManager> typed as ManagerService
    var s2 = GetService("another"); // returns ManagerService<AnotherManager> typed as ManagerService
}

How to get return value from switch statement?, function switchResult(a){ switch(a){ case 1: return "FOO"; case 2: No, the switch doesn't have a return value. properties in a JavaScript object and use functions as values instead of the logic in the individual case blocks. No, the switch doesn't have a return value. What you see in the console is the return value of the statement inside the switch containing only a string literal value. A statement can have a return value. An assignment for example has the assigned value as return value, and post-incrementing a value returns the result after incrementing:

Generally, as a consumer of generics, you should know the types you're working with at compile time - they're either a specific type you know and can pass directly as a generic type parameter or you're implementing something generic yourself and are passing through some type arguments.

You're trying to mix in runtime knowledge. This tends to be fragile even if you can make it work, and will tend to involve lots of excessive casting to "shut up" the compiler - even though it's warnings are valid and you're trading compile time safety for (possible) runtime errors.

So, if possible, try not to "defer" generic decisions until runtime. This should compile:

class ManagerService<T> where T : BaseManager
{

}

static ManagerService<T> GetService<T>(/* not needed? */string serviceName)  where T : BaseManager
{
    return new ManagerService<T>();
}

Because now we're letting the generic parameter determine our return type. Of course, at this point it's unclear if the string serves any purpose.

Even with your original code, you'd still have had to supply the correct type parameter at the callsite in order for it to compile, as you will with the above.

Replacing switch statements with Object literals, In many programming languages, the switch statement exists - but should it any longer? maintainability and we don't need to manually break; each “case”. Let's set up a simple Object literal that returns a String value only. An Object as a switch case is too non‑specific. The switch on Strings was specifically requested by users. There was probably no demand for switching on plain simple Objects. Now look how much more complicated the bytecode is for Strings. It would be even worse for any kind of Object.

Since you commented that you want to determine the type of manager based on a string you get from the database:

If you don't know the type of manager at compile time, then maybe you want to go with this dependency injection approach instead:

(If this is going to work depends on how your BaseManager and ManagerService are implemented.)

// common interface for all manager implementations
interface IManager
{ }

// optional: basic implementation
abstract class BaseManager : IManager
{ }

class FooManager : BaseManager
{ }

class AnotherManager : BaseManager
{ }

class ManagerService
{
    // constructor accepting the IManager implementation
    public ManagerService(IManager manager);
}

static ManagerService GetService(string serviceName)
{
    switch(serviceName)
    {
        case "foo":
            return new ManagerService(new FooManager());
        case "another":
            return new ManagerService(new AnotherManager());
    }
    throw new ArgumentException("Service not found");
}

static void Main(string[] args)
{
    var serviceBase = GetService("foo"); // Returns ManagerService using the FooManager implementation
    var serviceAnother = GetService("another"); // Returns ManagerService using the AnotherManager implementation
}

Why I prefer objects over switch statements, If you don't add the break keyword to your switch statement it wont throw to save and return a string conditionally, using objects we could do:. Relatively rare use of switch and case operators is one of the hallmarks of object-oriented code. Often code for a single switch can be scattered in different places in the program. When a new condition is added, you have to find all the switch code and modify it. As a rule of thumb, when you see switch you should think of polymorphism. Treatment

Pattern Matching, But, you'll do it without resorting to object-oriented techniques and building Length) { case 0: return "No elements to the input"; case 1: return $"One Code execution can't "fall through" from one case expression to the next;  The following example shows a simple switch statement that has three switch sections, each containing two statements. The second switch section contains the case 2: and case 3: labels. A switch statement can include any number of switch sections, and each section can have one or more case labels, as shown in the following example. However, no two case labels may contain the same expression.

default value expressions, You also use the default keyword as the default case label within a switch statement. WriteLine(default(object) is null); // output: True void default) { if (​length < 0) { return default; } var array = new T[length]; for (var i = 0;  The break statement is required in case 1 and case 3. If you omit it, the code will not compile, because the if body is not guaranteed to execute, and fall-through in switch statements is not allowed in C#. The break statement is not required in case 0 and case 2, because the return always executes; code execution will never reach the break statement.

Strings in switch Statements, In the JDK 7 release, you can use a String object in the expression of a switch statement: switch (dayOfWeekArg) { case "Monday": typeOfDay = "Start of work week"; break; case day of the week: " + dayOfWeekArg); } return typeOfDay; }. Welcome › Forums › General PowerShell Q&A › How to use result of switch/if as property in Select-Object? This topic has 6 replies, 3 voices, and was last updated 4 years, 11 months ago by Rob Simmers

Comments
  • That someone could call GetService<AnotherManager>("base") and what you want to do would break type safety? In such a case, your signature promised to return a ManagerService<AnotherManager. That's not what your code would do.
  • @Damien_The_Unbeliever I updated my question. So there is no way to do this? The thing is I want to have a switch statement to return object depending on string input. I am doing this several times in my code, so I dont want to duplicate this.
  • I am getting string serviceName from database, so this is why I am passing this as a string.
  • @dafie if this won't work for you, you should take a look at the dynamic keyword
  • @dafie - but such code will not compile unless you can supply the correct type argument, T, at the callsites for the GetService method. So you still have to know what the correct type is.
  • I added an alternative approach using a non-generic GetService() method.
  • @PeterB I already tried this. I am getting error Cannot implicitly convert type 'app.ManagerService<app.FooManager>' to 'app.BaseManager'