C
C#2w ago
Tofaa

Have public static values accessible thru the class that inherited this class

I understand the title is rather silly but i couldnt word it properly to fit a title. I come from a java background, and am currently making something where i require an exposed api interface and also code-generated values inside the interface. For clutter reasons I'd like to seperate the interface and the static methods. In java for example
public sealed interface A extends VariousAs {
}

class AImpl {}

interface VariousAs {

A VALUE_ONE = new AImpl();
A VALUE_TWO = new AImpl();
}
public sealed interface A extends VariousAs {
}

class AImpl {}

interface VariousAs {

A VALUE_ONE = new AImpl();
A VALUE_TWO = new AImpl();
}
In the code above i can easily access A.VALUE_ONE without exposing AImpl and VariousAs, but theres no way (atleast from what i can tell) to replicate such behaviour in c#.
10 Replies
cap5lut
cap5lut2w ago
u will have to access it via TypeName.StaticMemember where TypeMember is the one declaring the static member, there is no other way in c#. well, there are static abstract members for interfaces but thats something entirely different
Tofaa
Tofaa2w ago
slightly annoying But thank you
cap5lut
cap5lut2w ago
or, for example, do u want to have something like an interface IPacket, that dictates that each class that implements IPacket has to have a static property static int PacketId { get; }? then the later is exactly what u want
Tofaa
Tofaa2w ago
nah im trying to load content from a json file into my registry then have accessors for each type without having to use the id string the later gets loaded by a python script atm since i couldnt find any c# code generators, but id still like to hide these impls from the actual interface of data
cap5lut
cap5lut2w ago
tbh, its still a bit hard to grasp what you are tryting to extension methods come to mind, but this is under the hood just static methods where the first parameter is an instance of the type u want to extend
Tofaa
Tofaa2w ago
Look at the java example or in c# i suppose it would be
public interface IRandomInterface : IRandomInterfaces;
internal interface IRandomInterfaces {

public static IRandomInterface VALUE_ONE = new RandomImpl();
}
internal class RandomImpl : IRandomInterface {}
public interface IRandomInterface : IRandomInterfaces;
internal interface IRandomInterfaces {

public static IRandomInterface VALUE_ONE = new RandomImpl();
}
internal class RandomImpl : IRandomInterface {}
I want to access VALUE_ONE from IRandomInterface and leave the implementation details hidden away I dont see a reason as to why this isnt possible as both IRandomInterface and VALUE_ONE have public modifiers this makes hiding away implementation much easier rather than exposing IRandomInterfaces In my current case atleast, im parsing attribute modifiers from a json. Once parsed theyre stored in a Registgry<IAttribute> and can be accessed using the Get method in the registry but require a key (string) to get. As you can tell, this would be really annoying to work with if i need to access them a ton of time, and if i change the key i need to refactor everything
public interface IAttribute {

public double DefaultValue {get;}
public NamespaceID Id {get;}
}

internal record AttributeImpl(NamespaceId Id,. double DefaultValue);
public interface IAttribute {

public double DefaultValue {get;}
public NamespaceID Id {get;}
}

internal record AttributeImpl(NamespaceId Id,. double DefaultValue);
I have hundreds of these inside the registry, so putting them in IAttribute as static methods would be manual and very annoying to write, so i codegenerate a hidden interface in java which has all the accessors that makes it really easy to use. In c# it would be something like
internal interface IAttributes {

public static readonly IAttribute HEALTH = Registry.Get("health"); // etc etc, you get the point

}
internal interface IAttributes {

public static readonly IAttribute HEALTH = Registry.Get("health"); // etc etc, you get the point

}
And I was hoping i could extend IAttributes in IAttribute and be able to access the publicly exposed fields in IAttributes directly from the IAttribute interface
cap5lut
cap5lut2w ago
u can use static usings for that. imagine u have in the namespace Example this class (the one u would generate)
public static class Attributes
{
public static readonly IAttribute Health = Registry.Get("health");
public static readonly IAttribute Example = Registry.Get("example");
}
public static class Attributes
{
public static readonly IAttribute Health = Registry.Get("health");
public static readonly IAttribute Example = Registry.Get("example");
}
then u can statically import Attributes and use every the static members without prefixing the name:
using static Example.Attributes;

Console.WriteLine(Health);
Console.WriteLine(Blah);
using static Example.Attributes;

Console.WriteLine(Health);
Console.WriteLine(Blah);
but thats the closest u get i think and u would still need to know the type for the static usings
Tofaa
Tofaa2w ago
oof This makes it even dumber as to why you cant directly access it if you can from a static import
cap5lut
cap5lut2w ago
looks cleaner to me than extending/implementing a bunch of interfaces just for that. static imports have zero overhead while a complexer type hierarchy brings in overhead
Tofaa
Tofaa2w ago
It's not a complex heirarchy though, and I don't wanna rely on static importing every time i wanna access it It's also just api design in general and i think a c# design flaw because its clearly public not to mention It makes my codegeneration step lile 100x more complicated rather than just an empty interface (easy to write and follow) i also need to follow the methods and fields inside the interface to accidentally not write over them