8

Please excuse bursts of stupidity as I learn the intricacies of C# / .NET

Say I have three classes with multiple static properties (more than three but for arguments sake..)

 CLASS FOO

    public static A
    { 
       get / set A;
    }   
    public static B
    {
       get / set B;
    }   
    public static C
    {
       get / set C;
    }   

 CLASS BAR
     {
        get / set A;
     }
    public static B
    {
       get / set B;
    }   
    public static C
    {
       get / set C;
     }   

 CLASS YOO
     {
        get / set A;
     }
    public static B
    {
       get / set B;
     }   
    public static C
    { 
       get / set C;
    }   

And from another class I need to update one or several static properties in each class multiple times... How do I keep from writing multiple SWITCH statments like this...

 public void updateVarx(string class, string varx)
 {
   string y = 'class'
   SWITCH (y)
   {
      case FOO:
       FOO.A = Varx;
       break;
      case BAR:
       BAR.A = Varx;
       break;
      case YOO:
       YOO.A = Varx;
      break;
   }
 }

And then another one when I want to update B varY:

 public void updateVary(string class, string vary)
 {
   string y = 'class'
   SWITCH (y)
   {
     case FOO:
      FOO.B = Vary;
      break;
     case BAR:
      BAR.B = Vary;
      break;
    case YOO:
      YOO.B = Vary;
      break;
   }
 }
12
  • Why they have to be static properties? Commented Mar 24, 2011 at 23:24
  • cause I don't want multiple instances of them... but dunno besides that.. they are status variables for a fixed set of securities Commented Mar 24, 2011 at 23:27
  • "Please excuse bursts of stupidity" may be the best phrase I've encountered this morning. It's hilarious, in a non-condescending way :) Commented Mar 24, 2011 at 23:27
  • I said I was learning, what is smelly ?? thanks @bolt Commented Mar 24, 2011 at 23:27
  • @CraigJSte: I think he's referring to what we call code smell. Commented Mar 24, 2011 at 23:28

6 Answers 6

4

Since you are learning .net/c#, I guess i should warn you, using static properties is probably not the way to go in object oriented programming.

Static is global state and is dangerous. If you end up using multi-threaded code, you have to be super careful. If you need only one instance, just instantiate one, but don't go creating static properties on a class, unless you have a pretty good reason to add them (And I can't think of any right now).

In fact, in well designed, object oriented code you sould probably not have many if, switch, getters or setters either.

Let's say you need different behaviors on your classes, you can do it this way.

Interface ISecurity {
  void UpdateVarX(int value);
  void UpdateVarY(int value);
  int GetValueX();
  int GetValueX();
}

class Foo:ISecurity {
  // Implement methods of the interface
}

class Bar:ISecurity {
  // Implement methods of the interface
}

class Yoo:ISecurity {
  // Implement methods of the interface
}

// This class is the class that uses your other classes
class Consumer 
{
  private ISecurity sec;

  public Consumer(ISecurity sec) {
    sec.UpdateVarX(25);
  }
}

Or if as in your example, all your static classes have the same properties:

public class Settings {
  public int A {get; set;}
  public int B {get; set;}
  public int C {get; set;}
}

public class NeedsToUseOtherClass {
  public NeedsToUseOtherClass() {
    Settings foo = new Settings();
    Settings bar = new Settings();
    Settings yoo = new Settings();

    foo.setA(25);
  }
}
Sign up to request clarification or add additional context in comments.

9 Comments

What do you mean "in well designed, object oriented code you sould probably not have many if, switch, getters or setters either?"
Question for you ... @Martin... 'only instantiate one' -- if I instantiate at the top of the class, does that mean it's only done once?
@Josh M. For the getters and setters, if you have them, it means you are exposing your object's internal state instead of having behaviors on your objects, which means your object's consumers know more than they sould know. For the switch and ifs, if you have a check against a type (typeof), you have something wrong in your code. Check antiifcampaign.com for more details
@CraigJSte In object oriented programming, a class is a kind of blueprint for an object. Each time you use the new keyword, the constructor of a class is called and you receive a new instance. If you use the new keyword only once on a class, you wil only instantiate one. You can then share this instance between method calls, store it as a private member and use it when needed.
@Josh M. Yes, but often, if you have a lot of nested ifs, switch cases, resulting in a lot of indentation, there is probably something wrong with your code.
|
2

Maybe I am not understanding the problem but if all your classes have the same exact properties then you can just pass the object (FOO, BAR, or YOO) into UpdateVarx or UpdateVary methods and just implement an interface? Something along these lines:

public class FOO : IHasStatus
{
    public A
    { 
       get / set A;
    }   
    public B
    {
       get / set B;
    }   
    public C
    {
       get / set C;
    }
} 

public void updateVarx(IHasStatus someObject, string varx)
{
    someObject.A = varx;
}
public void updateVary(IHasStatus someObject, string vary)
{
    someObject.B = vary;
}

15 Comments

@Pete , by Jove I think you've got it!! (for extra credit - who said that was it Sherlock Holmes)??
If the properties on FOO are static, they are not considered implementation for the interface properties.
@craigjste I hope so buddy. It sucks to have an issue without resolution.
@codenaked This is true, I copied and pasted his code. I don't think the status properties have to be static though, do they? I guess I'm having a hard time understanding why they are static to begin with.
@Pete - Not sure :-) Seemed like it.
|
1

If you don't need the concrete classes, you can abstract out the logic like so:

public class Status {
    public string A {
        get; set;
    }

    public string B {
        get; set;
    }

    public string C {
        get; set;
    }
}

public static class StatusManager {
    private static Dictionary<string, Status> statusMap = new Dictionary<string,Status>();

    public static Status GetStatus(string name) {
        Status status;
        if (!statusMap.TryGetValue(name, out status))
            statusMap[name] = status = new Status();
        return status;
    }

    public static void SetStatus(string name, Status status) {
        statusMap[name] = status;
    }

    public static void UpdateVarx(string name, string varx) {
        GetStatus(name).A = varx;
    }

    // ...
}

5 Comments

@Pete - Are you asking me or @CraigJSte? :-)
@pete I am not sure if it will but I do like it! - on second glance it likely will but I would have to brush up on DICT usage.. It's good though...
@craigjste This is a good place to start it looks like. If anything just brush up on Dictionary usage at MSDN.com. The Dictionary is the least of your problems here =P
@Pete = do you think I will let you get away with that so easily.. now tell me what you think the real problem is... :)
@craigjste To be honest I am not sure what the problem is but I know its not the dictionary. To me it seems like its easily solved using interfaces but I may be misunderstanding the domain of the problem.
0

If you are a fan of the javascript way of solving multiple switch cases like this

you can always wrap up the switch handlers as Actions and toss them in a Dictionary.

For example : (Source obtained from here)

   public class SwitchCase : Dictionary<string,Action>
    {
        public void Eval(string key)
        {
            if (this.ContainsKey(key))
              this[key]();
            else
             this["default"](); 
        }
    }


    //Now, somewhere else

            var mySwitch = new SwitchCase
            {
                { "case1",  ()=>Console.WriteLine("Case1 is executed") },
                { "case2",  ()=>Console.WriteLine("Case2 is executed") },
                { "case3",  ()=>Console.WriteLine("Case3 is executed") },
                { "case4",  ()=>Console.WriteLine("Case4 is executed") },
                { "default",()=>Console.WriteLine("Default is executed") },
            };

            mySwitch.Eval(c);

1 Comment

hmmm, I'll consider this @world, thnx, I'm gonna hope for a 'simpler' answer (yes I meant to put that in quotes), it could mean I'm not smart or it could mean I'm just simple :)
0

Below code uses all kinds of hacks, not really recommended in production code unless you have a very good reason.

using System;
using System.Linq;

namespace ConsoleApplication1
{
    static class Program
    {
        private static void SetStaticProperty(string className, string propName, string varx)
        {
            //This sucks, I couldnt find the namespace with easily through reflection :(
            string NAMESPACE = "ConsoleApplication1";
            Type t = Type.GetType(NAMESPACE + "." + className);
            t.GetProperties().Where(p => p.Name == propName).First().SetValue(null, varx, null);
        }

        public static void updateVarx(string className, string varx)
        {
            SetStaticProperty(className, "A", varx);
        }

        public static void updateVary(string className, string vary)
        {
            SetStaticProperty(className, "B", vary);
        }

        static void Main(string[] args)
        {
            updateVarx("Foo", "FooAstring");
            updateVarx("Bar", "BarAstring");
            updateVarx("Yod", "YodAstring");
            updateVary("Foo", "FooBstring");
            updateVary("Bar", "BarBstring");
            updateVary("Yod", "YodBstring");

            Console.WriteLine(Foo.A);
            Console.WriteLine(Foo.B);
            Console.WriteLine(Bar.A);
            Console.WriteLine(Bar.B);
            Console.WriteLine(Yod.A);
            Console.WriteLine(Yod.B);
            Console.ReadLine();
        }
    }

    class Foo
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }

    class Bar
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }

    class Yod
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }
}

5 Comments

any reason downvote? I warned at the top saying this is not a great piece of code, I was showing a possibility.
Sorry but I had to downvote. This is not the correct way to solve the problem which you stated yourself "not really recommended in production code".
yeah thats what I said. I think the technique is still useful in many cases. It was a way to show possibility.
I realise you warned at the beginning but still, this is a beginner trying to learn C#. Again, I rarely downvote but I just thought that this answer while it works its just not correct in this context, sorry :-)
Sorry for being a downer guys :-)
0

You can use dictionary as configuration and remove the switch statement Create a dictionary and add append data as below for mapping

//Have dictionary setted up
Dictionary<string, dynamic> m_Dictionary = new Dictionary<string, dynamic>();
m_xmlDictionary.Add("classA",FOO);
m_xmlDictionary.Add("classB",BAR);
m_xmlDictionary.Add("classC",BAR);
//Have dictionary setted up


//change the function as below
public void updatevarx(string class, string varx)
{
    m_Dictionary[class].A=varx // Replaced switch statement
}

//while calling use
updatevarx("classC","abc!");// This will assign BAR.A with abc!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.