# Why does Powershell behave this way with classes?

**URL:** <https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164>\
**Category:** Open Discussions\
**Created:** [December 14, 2022, 11:43pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164 "2022-12-14T23:43:14Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Random-User](https://avatars.discourse-cdn.com/v4/letter/r/7bcc69/32.png) [@Random-User](https://forums.powershell.org/u/Random-User)\
**Post date:** [December 14, 2022, 11:43pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/1 "2022-12-14T23:43:14Z")

</div>

I notice that, when I attempt to create a class B inside a class A declared as Class A{} putting Class B{} inside Class A, it appears the error:

```auto
At line:3 char:5
+ {
+ ~
Missing closing '}' in statement block or type definition.
At line:8 char:5
+ }
+ ~
Unexpected token '}' in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndCurlyBrace

```

When I modify Class B{} to B(){}, the program accepts the creation of Class A without problems. If I attempt to insert C(){} in B(){}, then it appears the following error:

```auto

At line:6 char:11
+ C(){}
+ ~
An expression was expected after '('.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedExpression

```

So I have figured out that, in order to create a class inside a class, create a class inside a class inside a class, and so on, I have to alternate between classes which are declared as Class ClassName(){} and ClassName(){}. Why does that happen and why do the errors happened when I inserted the parenthesis and brackets presumably in a decent way in the code? Thanks.

---

<div class="post-metadata">

**Author:** ![krzydoug](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/krzydoug/32/1008_2.png) [@krzydoug](https://forums.powershell.org/u/krzydoug)\
**Post date:** [December 15, 2022, 2:17am UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/2 "2022-12-15T02:17:15Z")

</div>

Can’t really tell you much about the issues with your classes without seeing them.

---

<div class="post-metadata">

**Author:** ![Random-User](https://avatars.discourse-cdn.com/v4/letter/r/7bcc69/32.png) [@Random-User](https://forums.powershell.org/u/Random-User)\
**Post date:** [December 15, 2022, 10:46am UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/3 "2022-12-15T10:46:45Z")

</div>

The first one is `Class A{Class B{}}`, which returns the first error. Then when I type `Class A{B(){}}`, the program works fine. When I type `Class A{B(){C(){}}}`, it returns the second error. Apparently I’ve mistaken a function with a class, because when I type `Class A{B(){}}; $AA = New-Object A; $AA.B`, it appears

```auto

OverloadDefinitions
-------------------
void B()

```

So I would like to know how to create a class inside a class in Powershell. If someone knows it, please tell me.

---

<div class="post-metadata">

**Author:** ![metablaster](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/metablaster/32/1224_2.png) [@metablaster](https://forums.powershell.org/u/metablaster)\
**Post date:** [December 15, 2022, 11:16am UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/4 "2022-12-15T11:16:20Z")

</div>

> [@Random-User](#):
>
> Class A{Class B{}}

it seems PS doesn’t support nested classes, there are 2 workarounds:

[https://social.technet.microsoft.com/Forums/en-US/7cb269b3-eb5c-4078-9f12-351d0f76b5ff/how-to-use-nested-c-classes-in-powershell?forum=winserverpowershell](https://social.technet.microsoft.com/Forums/en-US/7cb269b3-eb5c-4078-9f12-351d0f76b5ff/how-to-use-nested-c-classes-in-powershell?forum=winserverpowershell)

or

> **[.Net Pointers: Useful PowerShell, Programming, and .NET articles](http://blogs.embrs.net/Article/Index/Creating%20an%20Instance%20of%20a%20Nested%20Class%20in%20PowerShell)**
>
> String Formatting in PowerShell

---

<div class="post-metadata">

**Author:** ![Random-User](https://avatars.discourse-cdn.com/v4/letter/r/7bcc69/32.png) [@Random-User](https://forums.powershell.org/u/Random-User)\
**Post date:** [December 15, 2022, 12:34pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/5 "2022-12-15T12:34:42Z")

</div>

This worked:

```auto
$sA = @'
  public class A {
    public string s1;
    public class B {
      public string s2;
    }
  }
'@

```

This didn’t work:

```auto
                                       
 public class Turkey
 {
   public Turkey() { }

   public virtual void GetDetails()
   {
     Console.WriteLine("Age: {0}", this.Age);
     Console.WriteLine("Breed: {0}", this.Breed);
   }

   public string Breed
   {
      get;
      set;
   }

   public int Age
   {
      get;
      set;
   }

    /// 

    /// A Wild Turkey is a nested subclass of Turkey
    /// 

    public class WildTurkey : Turkey
    {
    public WildTurkey() { }

    public override void GetDetails()
    {
    base.GetDetails();

    Console.WriteLine("Region: {0}", this.Region);
    }

    public string Region
    {
       get;
       set;
    }
   }
 }

```

I’ve edited the first code and then inserted the above code in the edited first code, and it worked. Here is the code:

```auto
$sA = @'
   public class Turkey
 {
   public Turkey() { }

   public virtual void GetDetails()
   {
     Console.WriteLine("Age: {0}", this.Age);
     Console.WriteLine("Breed: {0}", this.Breed);
   }

   public string Breed
   {
      get;
      set;
   }

   public int Age
   {
      get;
      set;
   }

    /// 

    /// A Wild Turkey is a nested subclass of Turkey
    /// 

    public class WildTurkey : Turkey
    {
    public WildTurkey() { }

    public override void GetDetails()
    {
    base.GetDetails();

    Console.WriteLine("Region: {0}", this.Region);
    }

    public string Region
    {
       get;
       set;
    }
   }
 }

'@

```

This is a quite weird syntax, to be sincere, so I’ve to accustom myself with it. Furthermore, could someone explain me what is the so-called .NET, whether it is “native” to Powershell, and what is the relationship between the so-called .NET and Powershell. I’ve noticed that there is a similarity between C#, which appears to be related to the so-called .NET, and Powershell. Both C# and Powershell appear to have importing functionalities which use the same resources and they both appear to use stuff with a syntax which goes like Windows.System, System.Objects, etc… Thanks.

---

<div class="post-metadata">

**Author:** ![Random-User](https://avatars.discourse-cdn.com/v4/letter/r/7bcc69/32.png) [@Random-User](https://forums.powershell.org/u/Random-User)\
**Post date:** [December 15, 2022, 1:20pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/6 "2022-12-15T13:20:13Z")

</div>

How do I access Class B and S2 in this code:

```auto
$ClassInstantiation = @'
  public class A {
    public string s1 = "HelloWorld";
    public class B {
      public string s2 = "HelloWorld2";
    }
  }
'@

Add-Type -TypeDefinition $ClassInstantiation -IgnoreWarnings;
$ClassMember = New-Object A;
$ClassMember;

```

The result of this code is the following:

```auto

s1
--
HelloWorld

```

It doesn’t appear Class B and S2  
Edit: In the following code, I can access s2 but not s1:

```auto
$sA = @'
  public class A {
    public string s1 = "Hello World";
    public class B {
      public static string s2 = "Hello World 2";
    }
  }
'@

Add-Type -TypeDefinition $sA

[A+B]::s2

```

The result of the code is:  
`Hello World 2`  
If I type `[A]::s1`, it appears nothing as result.

---

<div class="post-metadata">

**Author:** ![metablaster](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/metablaster/32/1224_2.png) [@metablaster](https://forums.powershell.org/u/metablaster)\
**Post date:** [December 15, 2022, 3:01pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/7 "2022-12-15T15:01:01Z")

</div>

> [@Random-User](#):
>
> `If I type [A]::s1, it appears nothing as result.`

You can’t access an instance of `B` if you don’t create one.

Don’t know how to create it in addition to `[A+B]` but try with: `New-Object A.B`

---

<div class="post-metadata">

**Author:** ![krzydoug](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/krzydoug/32/1008_2.png) [@krzydoug](https://forums.powershell.org/u/krzydoug)\
**Post date:** [December 15, 2022, 3:33pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/8 "2022-12-15T15:33:06Z")

</div>

See how you marked class b s2 as static? That’s a static property so it can be accessed like shown. Without static it’s an instance method, meaning you have to instantiate an instance of the object to access the property. These are basic class rules, same for c#

---

<div class="post-metadata">

**Author:** ![Random-User](https://avatars.discourse-cdn.com/v4/letter/r/7bcc69/32.png) [@Random-User](https://forums.powershell.org/u/Random-User)\
**Post date:** [December 15, 2022, 5:32pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/9 "2022-12-15T17:32:09Z")

</div>

> [@metablaster](#):
>
> > [@Random-User](#):
> >
> > `If I type [A]::s1, it appears nothing as result.`
> 
> You can’t access an instance of `B` if you don’t create one.
> 
> Don’t know how to create it in addition to `[A+B]` but try with: `New-Object A.B`

If I put this in the code:

```auto

$sA = @'
  public class A {
    public string s1 = "Hello World";
    public class B {
      public static string s2 = "Hello World 2";
    }
  }
'@

Add-Type -TypeDefinition $sA
New-Object A.B

```

And press the enter keyboard button, it appears the error as follows:

```auto
New-Object : Cannot find type [A.B]: verify that the assembly containing this type is loaded.
At line:12 char:1
+ New-Object A.B
+ ~~~~~~~~~~~~~~
    + CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

```

> [@krzydoug](#):
>
> See how you marked class b s2 as static? That’s a static property so it can be accessed like shown. Without static it’s an instance method, meaning you have to instantiate an instance of the object to access the property. These are basic class rules, same for c#

If I code this

```auto

$sA = @'
  public class A {
    public static string s1 = "Hello World";
    public class B {
      public static string s2 = "Hello World 2";
    }
  }
'@

Add-Type -TypeDefinition $sA;
$A = New-Object A;
[A+B]::s2;
[A]::s1;

```

And press the enter keyboard button, it appears this:

```auto
Hello World 2
Hello World

```

So this works.  
I’ve found this works as well:

```auto
$Depth1 = @'
public class A
    {
    public string s1 = "Hello World 1";
    public string s2 = "Hello World 2";
    public string s3 = "Hello World 3";
    public class B
        {
        public string s4 = "Hello World 4";
        public string s5 = "Hello World 5";
        public string s6 = "Hello World 6";
        public class C
            {
            public string s7 = "Hello World 7";
            public string s8 = "Hello World 8";
            public string s9 = "Hello World 9";
            }
        public C c;
        public B()
            {
            c = new C();
            }
        }
    public class D
        {
        public string s10 = "Hello World 10";
        public string s11 = "Hello World 11";
        public string s12 = "Hello World 12";
        }
    public B b;
    public D d;
    public A()
    {
    b = new B();
    d = new D();
    }
  }
'@

Add-Type -TypeDefinition $Depth1
$a = New-Object A

```

The classes must be public for it to work. I can access the variable s4 of class B inside class B through $a.b.s4. When I type [A+B]::s4 in the console and then press the enter keyboard button, the code doesn’t leave any results.

If I write this

```auto

$sA = @'
public class A
    {
    public static string s1 = "Hello World 1";
    public static string s2 = "Hello World 2";
    public static string s3 = "Hello World 3";
    public class B
        {
        public static string s4 = "Hello World 4";
        public static string s5 = "Hello World 5";
        public static string s6 = "Hello World 6";
        public class C
            {
            public static string s7 = "Hello World 7";
            public static string s8 = "Hello World 8";
            public static string s9 = "Hello World 9";
            public class D
                {
                public static string s10 = "Hello World 10";
                public static string s11 = "Hello World 11";
                public static string s12 = "Hello World 12";
                }
            }
        }
    }
'@

Add-Type -TypeDefinition $sA;
$A = New-Object A;

```

Then I press the enter keyboard button, then I can access the class properties using brackets, and I’m not capable of accessing the class properties using a dot, for instance, if I type [A]::S1, I’m capable of accessing the property S1 of A, and if I type $A.S1, I’m not capable of accessing property S1 of A (it shows no result), unlike the function right above this one, which is the inverse.

---

<div class="post-metadata">

**Author:** ![krzydoug](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/krzydoug/32/1008_2.png) [@krzydoug](https://forums.powershell.org/u/krzydoug)\
**Post date:** [December 15, 2022, 7:51pm UTC](https://forums.powershell.org/t/why-does-powershell-behave-this-way-with-classes/21164/10 "2022-12-15T19:51:30Z")

</div>

I think the really important question here is, what are you trying to accomplish?

> [@Random-User](#):
>
> So I would like to know how to create a class inside a class in Powershell. If someone knows it, please tell me.

Is this the question? Typically, you would not create a class “inside” another class. You would extend or inherit from the class. I think if you provided a better “real world” example of what you’re hoping to achieve, we could better assist you.

And of course, if you haven’t done so already, read this [article](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-7.3) in it’s entirety.
