-4

I have tried to create an array of classes, first of regular classes, then of static classes, in both cases, it hasn't worked. It hasn't compiled.

class Program
{

    static class A : Bunch1 { }

    static class B : Bunch1 { }

    class AA : Bunch2 { }

    class BB : Bunch2 { }

    class Bunch1 { }
    class Bunch2 { }

    static void Main(string[] args)
    {
        Bunch1[] bunch1s = new Bunch1[] {
            A,B
        };

        Bunch2[] bunch2s = new Bunch2[] {
            AA,BB
        };
    }
}

The compilation error has been that AA "is a 'type' but is used like a 'variable'" (same error message for any class - A or B or AA or BB)

I can see that (at least for non static classes), I can do

        Bunch2[] bunch2s = new Bunch2[] {
            new AA(),new BB()
        };

But I don't want instances of those classes.

I don't want an array of objects.

Added

A practical scenario of why.

I have a bunch of classes each with a static field (public static char c), and i'd like to set that field.

class A { public static char c; }

class B { public static char c; }

....

I could say

A.c='x';
B.c='p';
C.c='w';
D.c='V';

But i'd rather say

char[] mychars= new char[] {'x','p','w','V'};

//  create a bunchofclasses array or list consisting of classes A,B,C,D (how, I don't know).


for(int i=0; i<5;i++)
 bunchofclasses[i].c= mychars[i];
barlop
  • 12,887
  • 8
  • 80
  • 109
  • What about using an array of types? – dreamlax Apr 22 '16 at 03:04
  • 4
    This doesn't make sense. Classes are not runtime objects. You can't have an array of them. – RJM Apr 22 '16 at 03:05
  • why would you need it? if only you can have arrays of class Types – Nitin Apr 22 '16 at 03:07
  • static classes are, as the error is saying a "type", i.e. a definition, not an instance you cannot do that as it wouldn't make sense. What you want to do is to make the classes non-static and use static variables inside to have a more static nature to support this use case. – Sumit Maingi Apr 22 '16 at 03:12
  • SO is wrong place to ask non-practical questions because one rarely can explain what actual goal is (short of "would not it be cool"). Please clarify your question with at least hypothetical use case. – Alexei Levenkov Apr 22 '16 at 03:17
  • @Ian your comment is somewhat strange since OP specifically said "I don't want an array of objects". – Alexei Levenkov Apr 22 '16 at 03:19
  • @SumitMaingi there isn't really such a thing as a non static class as you describe it.. A class where you don't specify 'static' can be used either statically or non-statically. A class where you specify static can only be used statically. So that is why it is possible to create a class that isn't declared as static and give it a static member, that is not nonsensical, and that's why such a thing would compile. – barlop Apr 22 '16 at 11:00
  • you'd have to use reflection. unfortunately you cannot specify static constraints in c#. – Dave Cousineau Apr 23 '16 at 00:04
  • @Sahuagin if you can use reflection and set the static variable, it'd be an answer.. but is it not possible to use reflection and set the static variable(since you mention that you cannot specify static constraints)? does it make a difference if you know the variable name(all classes have the same member variable name)? – barlop Apr 23 '16 at 20:00
  • I've added an answer with this approach. – Dave Cousineau Apr 24 '16 at 22:15

3 Answers3

1

Unfortunately, you can't have a static contract/constraint where some classes have been grouped by their static members so that you could generalize them and access static members abstractly. It could have been put into the language, but wasn't.

Nevertheless, you can still do something similar with reflection, it just won't be anywhere near as tidy as what you were aiming for.

class A { public static char c; }
class B { public static char c; }
class C { public static char c; }
class D { public static char c; }

var mychars = new char[] { 'a','b','c','d' };

var types = new[] {
   typeof(A),
   typeof(B),
   typeof(C),
   typeof(D)
};

for (int i = 0; i < types.Length; i++) {
   var type = types[i];
   var field = type.GetField("c", BindingFlags.Public | BindingFlags.Static);
   if (field == null)
      throw new InvalidOperationException("No such field.");

   // pass null as instance for static members, since there's no instance
   field.SetValue(null, mychars[i]);
}

Note that in the example, c is a field. You'd need to use a different method (GetProperty, GetMethod) for a different kind of member.

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
0

A, B, AA, BB are types. In your second example you are calling new AA()which is initializing an object of type AA which can be stored in an array.

However, you could store an array of strings that held the names of he types such as

string[] strTypeArray = { "AA", "BB" }

and then call

Type.GetType(strTypeArray[0]);

to get the type if you needed it.

EDIT - Answering Question in Comment

Q: Why does calling Type.GetType("AA") == null return true?

Because Type.GetType() takes AssemblyQualifiedName as the input string which requires the name of the assembly for which you are getting the type. Unfortunately for me I typed my initial response on my phone and didn't feel like typing more than I had to since this answer has been answered more than once.

If you change your call to Type.GetType("NameOfAssembly.AA") == null you will get a result of false and get what you are looking for.

However, just because you have the type that is not the same as having an instance of that type and you won't have access to any properties within that type until you have initialized it in some way.

It is possible to create an instance of a class based on its type and the information for that is readily available.

Community
  • 1
  • 1
Dmitry K.
  • 972
  • 6
  • 16
  • why is it that when I have `public class AA {}` then in a main method I do `Console.WriteLine(Type.GetType("AA")==null);` I get true ? – barlop Apr 23 '16 at 00:24
  • Thanks for addressing that comment. On another note- You mention about an instance, but I keep saying I do not want an instance of it, even my title is saying that,(no object thus no instance), and where you write " just because you have the type that is not the same as having an instance of that type and you won't have access to any properties within that type until you have initialized it in some way." <-- The first part of that sentence - that a type is not an instance, is of course true, I never said otherwise.. – barlop Apr 23 '16 at 08:36
  • The second part of that sentence, where you write " and you won't have access to any properties within that type until you have initialized it in some way" <--- I don't think that is true at all. You can have a static member and you do not make an instance to access it. – barlop Apr 23 '16 at 08:39
  • Ok I can appreciate your second point. If you stored an array of types (array of classes makes no sense) then you could use reflection to get the static property of a type without initializing it. – Dmitry K. Apr 23 '16 at 13:29
  • I think reflection is the way to go, i'm going to learn it. If you add how to do that with reflection, the code that does it then that'd answer the question, thanks – barlop Apr 23 '16 at 18:08
  • this line of yours `var strss = { "AA", "BB" };` gives an error though this works `string[] sdfs = { "asdf" ,"fdf"};` and this works `var strddss = new string[]{ "AA", "BB" };` – barlop Apr 23 '16 at 18:22
  • You're right it should be string[] strTypeArray = { "AA", "BB" }; I guess var can't interpret the short hand version of the array initializer. I've updated my comment. – Dmitry K. Apr 23 '16 at 18:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110024/discussion-between-barlop-and-dmitry-k). – barlop Apr 23 '16 at 18:25
0

You can create an array of Types

var types = new Type[]{typeof(AA), typeof(BB)}

However, you are not storing instance references of your classes AA or BB, just the types. If you want that you should use the keyword new and store the result in an array of base class,

Bunch2[] bunch2s = new Bunch2[] {
            new AA(),new BB()
        };

Also you can create objects from a Type(use the variable type) Activator.CreateInstance(types[0])

Btw you can't create arrays of static classes, also you can't create an instance of a static class.

Hope this helps

Zinov
  • 3,817
  • 5
  • 36
  • 70