0

I have a Material class :

public class Material
{
   public string Name { get; private set; }
   public double Density { get; private set; }
   public double SpecificHeat { get; private set; }
   public double Conductivity { get; private set; }

   public Material(string name, double d, double c, double l)
   {
      Name = name;
      Density = d;
      SpecificHeat = c;
      Conductivity = l;
   }
}

What is the way to go to provide default instances (in my case most commonly used building materials) ?

1) should I use some static properties in my class ?

public static Material GlassWool => new Material("GW", 0.3, 1000, 0.04);

2) should I use some static method with a switch over an enum ?

public enum CommonMaterial
{
    GlassWool,
    RockWool,
    WoodWool,
}
public static Material Common(CommonMaterial mat)
{
   switch(mat)
   {
      case GlassWool:
         return new Material("GW", 0.3, 1000, 0.04);
      default:
         return new Material("Generic", 1, 1, 1);
   }
}

3) would you see a more "easy to extend" way to do this, for instance relying on a JSON file with the default values ?

__ EDIT __

To give more context, my goal is to build a small API for the "conventional method for building-energy-efficiency assessment" in France. In this method :

  • If you know AND can justify the material of the wall you can go for it (possible for recent buildings)
  • Generally, you have a vague idea of what the material(s) of the wall is/are and there is a complex decision tree you HAVE to follow to get "defaults" wall materials according to various simple and non-destructive observations you can make on site.

Listening to all you valuable comments, what do you think about this mixed approach :

  1. doing a bit of templating with .tt and .json files to build static properties/method to expose the default values of the conventional method (following the decision tree).
  • the conventional values will not be editable by the consumer of the API
  • in the GitHub repo, the conventional data is readable as a json file. It is more transparent and easy to verify.
  • offers the right level of flexibility if the conventional method changes (likely to happen as it is still a wip)
  1. implement a consumer database in a separate .jsonfile that can be loaded at runtime. This way, the consumer can have its on default materials defined, the ones that he sees frequently on site.
5
  • #1 probably the most extended solution. #2 and #3 are too complicated.
    – Laiv
    Commented Dec 12, 2022 at 14:43
  • 6
    On a different note, I really dislike "double d, double c, double l" in the constructor. I initially assumed that "c" was conductivity, yet it appears to be specific heat. While I now know after a google search that "c" is the SI unit for specific heat, by not spelling it out ( as per your field names) you have forced me to think. And making people think isn't conducive in general to understanding code. And I have absolutely no idea where "l" comes from, as both electrical and thermal conductivity have totally unrelated SI symbols
    – Peter M
    Commented Dec 12, 2022 at 18:04
  • 1
    @PeterM: In saying that, there is some leeway here in case all of the developers are acutely aware of the meanings of these names, but in general I agree: full names cost nothing extra and pay back dividends.
    – Flater
    Commented Dec 13, 2022 at 8:40
  • @PeterM : I agree too ! Commented Dec 13, 2022 at 21:26
  • 1
    Just a suggestion: have your static properties only generate the object once: public static Material GlassWool { get; } = new Material("GW", 0.3, 1000, 0.04); (instead of public static Material GlassWool => new Material("GW", 0.3, 1000, 0.04);). Commented Dec 13, 2022 at 22:46

3 Answers 3

3

should I use some static properties in my class ?

This is fine. A typical example would be the System.Windows.Media.Colors class that contain a set of predefined colors. You should probably ensure the type is immutable and equatable, since that is at least the behavior I would expect.

You should probably also ensure that the values are truly constant, i.e. they are unlikely to ever change.

should I use some static method with a switch over an enum ?

Also fine, the main advantages of this is to use as references to some other source. You might for example want to store the actual properties for "GlassWool" in a database in case they need to be changed.

would you see a more "easy to extend" way to do this, for instance relying on a JSON file with the default values ?

Also fine. But if you do not have an enum you need to be able to handle values dynamically. This might be useful if you want the user to select materials from a drop down for example.

In the end the best method will depend on the specific use case. If the type is small and expected to rarely change I would lean toward static properties. If the type is larger or expected to change I would lean towards storing it a file or database. If you need to implement logic around values I would lean towards an enum, say for example if some material cannot be used in some specific cases, regardless of its actual properties. But then you might want to separate the material type from the material itself.

1

Its common to use a static for stuff like this.

eg

  • Guid.Empty
  • Color.Black
  • String.Empty

etc

https://learn.microsoft.com/en-us/dotnet/api/system.guid.empty?view=net-7.0

0

The issue with enshrining these default values into the codebase itself is that you need to rebuild and redeploy the codebase in order to make any change to these values. The alternative is to load them from a location that can be easily changed without needing to rebuild and redeploy the application. That could be a JSON file, config file, external database server, cloud storage, ...

For this specific example, I would very much favor putting this in some sort of configurable location and not baking it into the code.

This allows you to add, edit and remove entries as you see fit, without potentially running into deployment complexities that stem from hotfixing your prod version while your dev version is ahead. Not that it can't be done, but better a headache saved than a headache endured.


Just to be clear, the other options aren't wrong. There are cases where default static values make sense, such as Guid.Empty and String.Empty, but your materials seem much more prone to expressing a value of external importance, which makes it more likely that you'd want to change or extend these default materials at some point.

If I am wrong and you are adamant that you will not need to change/extend these ever, then a static property is an equally adequate solution. But my gut doubts that this is going to be the case.

1
  • I feel these values are unlikely to change generally, but I also feel like a few of them might change in the futur. Commented Dec 13, 2022 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.