Skip to content

[C# Feature Request] Hierarchy Data Type #16193

@RandyBuchholz

Description

@RandyBuchholz

Background

There are a few threads that talk about things like nested enums, and other need to represent hierarchal structures. To define a unique spot in a hierarchy we use things like nested namespaces, nested classes, or specialized parser classes. There is no built-in way. On occasion, just to be able to locate a typed-hierarchy object, I've even resorted to things like

namespace ServiceCatalog {
    namespace Member {
        namespace Membership {
            public abstract partial class Join {
                public enum Apply { SaveApplication, SubmitApplication }
                public enum Review { EvaluateApplication, SendNotifycations }
            }
        }
    }
}

so I can happily dot my way around magic strings and keep things unique in a hierarchy. (Please don't judge me...)

There have been discussions related to this like posts
Proposal: Record Enum Types #6739
Proposal: Nested enums #14720
Feature Request: enum to act like types #3704

But I think it may make more sense to create a new type instead of modifying existing types.

Proposal

Create a new datatype "Hierarchy" that represents a hierarchy of Type.
Conceptually

Enumerable<Type>{
    Enumerable<Type>{
        Enumerable<Type>{}
    }
}

This type could be used in whole or part, to locate types in a hierarchy, or even serve as a meta-type.

It could be used alone, like a nested "enum":

Hierarchy Level0.Level1.Level2.Value = "Green";

Hierarchy Level0.Level1.Level2.Values[] = { Green, Red, Yellow }

Hierarchy PrimaryColors { Reds, Blues }
    .Reds { Pink, Blood }
    .Blues { Sky, Navy }

It could also be typed. Each level could represent a different type, but they may need to be restricted to primitives initially.
Just a few different syntax ideas-

Hierarchy<string> Menu { "File", "Edit", "Contact Us" }
    .[File] { "Save", "Close" }
    .[Contact Us] { "Phone", "Email" }

// or (convoluted) example of meta-type definition. This could def partial classes, and even inherit.
Hierarchy Shapes<class> { Rectangle, Ellipse }
    .Rectangle<class> { Square : Rectangle , Rectangle }
        .Square<string> { "Big Square", "Little Square" } 
    .Ellipse<class> { Circle, Ellipse }

Type squareType = typeof(Shapes.Rectangle.Square); // = Class
Type squareType = typeof(Shapes.Rectangle.Square.[Little Square]); // = string (don't like this syntax though)

They should be usable in most places you can use any other basic type.

  1. Can declare inside local function
  2. Should have shorthand syntax (see next code)
  3. Support basic "stringish" functionality
// Shorthand creation (see Item 6 - they are partials, so this doesn't redefine)
Hierarchy TwoQuickNodes.UpperLevel.LowerLevel.LowestLevel
Hierarchy TwoQuickNodes.UpperLevel.AnotherLowerLevel

// Shorthand with "..." and stringformat
var shapesDir = Shapes...Square.ToString("/");
// gives "Shapes/Rectangular/Square" 

// Or sub section
var shapesDir = Shapes[Rectangle...Square];
// produces "Rectangle.Square" 
  1. Can use in attribute parameters. You can no longer use enums in attribute parameters. If a Hierarchy is a primitive, you should be able. (See next code)

  2. Understand uniqueness. If an element is unique in the hierarchy, it can be addressed directly

// Working similar to an enum, with underlyingType an int
Hierarchy<int> ServiceRoutes { Provider1, Provider2, Provider3 }
    .Provider1 { Interface1, Interface2 }
         .Interface1 { Operation1, Operation2 }
    .Provider2 { Interface1, UniqueName }

[Route(ServiceRoutes[UniqueName]-String('/')] // .ToString() can't be used on attribute params, so something else.
 ActionResult SomeAction(){...}

// produces => "ServiceRoutes/Provider1/UniqueName"

  1. Extensible and inheritable. We should be able to derive Hierarchies from Hierarchies. We should also be able to extend them (at design time) from multiple locations. They are inherently partial.
// Using ServiceRoutes from the previous code
Hierarchy<int> ServiceRoutes.Provider1.Interface1 { AddedOperation }

// Understanding uniqueness also works for creation shorthand.
// This adds a two levels below UniqueName
Hierarchy ServiceRoutes[UniqueName] { Child1.Child1dot1 }

I think there is a need to be able to represent hierarchies as true hierarchies, and not have to manually construct nested objects. I don't know what that should actually look like, but I thought I would put out a few ideas.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions