3

Can I locally reference a class in C#, instead of an instance of a class? The following code won't compile but, as an example, something like:

void someFunc()
{
    var a = System.Math;
    var b = a.Abs(4);
}

edit: In the real program it's not the System.Math class and I'm wanting to construct the class and return the constructed value. I didn't think originally that the context in which I wanted to use the class would be relevent, and probably it shouldn't be.

Anastasiosyal has an interesting idea with using a local Delegate to do it.

alan2here
  • 3,223
  • 6
  • 37
  • 62

6 Answers6

8

You can reference a class:

Type math = typeof(System.Math);

But you cannot call static methods on it using regular dot syntax:

// Wont compile:
math.Abs(5);

If you just want to shorten (and IMHO obfuscate) your code, you can reference classes with aliases via a using directive:

// Untested, but should work
namespace MyUnreadableCode {
    using m = System.Math;
    class Foo {
        public static Int32 Absolut(Int32 a) {
            return m.Abs(a);
        }
    }
}
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • In C# 4, it is possible to invoke the static methods on `Type` objects using the new `dynamic` keyword. It requires some additional plumbing (and it isn't pretty), but it works. ([Source](http://blogs.msdn.com/b/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx)) – M.Babcock Feb 20 '12 at 17:26
  • The Type approach as you say dosn't allow for calling of static methods, and by the look of it calling anything without lots of obfuscation, and the namespace approach dosn't allow the using statement to be very local, although it might be the best available in this case. I'm usually not a fan of "using", for example I don't like long lists of "using" at the top to make a namespace hierarchy like the one that starts "System" seem flat. – alan2here Feb 20 '12 at 17:32
  • I'm actually running on an environment possibly due to XNA where "dynamic" doesn't work properly. Although, as controversial as this will seem to C# coders, I'm a big fan of it and don't think it compromises safety. – alan2here Feb 20 '12 at 17:35
  • 1
    I have no problem with flattening namespaces with using directives (the 'classic' use of `using`). I just think that aliasing is particularly messy, since it interrupts my ability to read the code in a huge way. – Chris Shain Feb 20 '12 at 17:36
4

You cannot assign a variable a value of a static class. The question is why would you want to do this, there are probably other ways that you could tackle your problem

e.g. you could use delegates to assign the operation you want to perform:

Func<int,int> operation = Math.Abs; 
// then you could use it like so: 
int processedValue = operation(-1);
Anastasiosyal
  • 6,494
  • 6
  • 34
  • 40
  • It's an interesting idea that could work, and could be the best solution so far, although the operation in my case is construct and return, the maths class is just an example, and what's more with a long argument list I ideally don't want to end up with a duplicate description of. I don't see how there being alternative ways of achieve the same thing makes my original approach wrong, it's just not avalible in C#. – alan2here Feb 20 '12 at 17:54
  • If you are looking for a creation pattern, you would benefit from a factory pattern or [Inversion of Control](http://en.wikipedia.org/wiki/Inversion_of_control) as described [Here](http://stackoverflow.com/questions/2515124/whats-the-simplest-ioc-container-for-c) – Anastasiosyal Feb 20 '12 at 19:11
  • This is the closest to being what I needed and has described, marked as correct, sorry for the delay. – alan2here Aug 09 '16 at 17:25
2

In C# 6.0 they introduced a static import feature, which can solve the problem.

using static System.Math;

class MyProgram
{
    static void Main(string[] args)
    {
        var b = Abs(4); // No need to specify the name of Math class
    }
}
Community
  • 1
  • 1
Andrej Adamenko
  • 1,650
  • 15
  • 31
2

In c# they're called Types. And you can assign them like:

Type a = typeof(SomeClass);

However, you would have to instantiate it to use it. What I believe you want is a static import like in java, but unfortunately, they do not exist in c#.

Short answer: Not like what you have above.

OnResolve
  • 4,016
  • 3
  • 28
  • 50
1

As I understand you need to refer to the class with short name? try this (on top of the file, inside using statements section):

using m = System.Math;

later in your code:

m.Abs(...)

Makes sense?

M.Babcock
  • 18,753
  • 6
  • 54
  • 84
Tengiz
  • 8,011
  • 30
  • 39
0

No. It's not possible to treat a Type as a value where instance methods bind to static methods on the original type. In order to do this you would need to construct a new type which forwards it's method calls to the original type.

class MyMath { 
  public int Abs(int i) {
    return Math.Abs(i);
  }
}

var x = new MyMath();
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Possibly you'r example could be improved with inheritance, MyMath inherits from System.Maths – alan2here Feb 20 '12 at 17:41
  • @alan2here why would that improve things? – JaredPar Feb 20 '12 at 17:42
  • Because then MyMath would be identical to System.Math instead of just having the one forwarding function. – alan2here Feb 20 '12 at 17:49
  • 1
    @alan2here that's not true though. The only thing interesting in `System.Math` are it's static methods and sattic methods don't participate in inheritance. Additionally `System.Math` is a static class and hence can't be inheritted from. – JaredPar Feb 20 '12 at 17:51