What is the idiomatic use case for static fields inside interfaces? - c#

I've searched through this website for anything tagged c# static interface and found that the topic rarely comes up. Examples from other websites have been similarly unsatisfactory and I've yet to come up with anything myself. I've therefore found it difficult to think of a use case for interfaces that include static fields.
Is there any design pattern, or any other idiom, that recommends the usage of a static field inside of an interface?

Traditionally interfaces are just contracts and do not contain executable code or state information but only contain abstract instance members that must be implemented by a class or a struct. Two features introduced in C# 8.0 and C# 11 add static members to interfaces. Only the first one adds executable code to the interface and possibly with it the need to save state:
In C# 8.0 Microsoft has introduced default interface methods. It is optional for a class to implement these methods. If they are not implemented, the default implementations kick in. However, these methods are not inherited by the class and can only be called through the interface (even within the class implementing the interface).
The primary motivation is to allow extending an interface without breaking existing code.
Static fields and other members not being part of the public interface are there to support the implementation of those default interface methods. The C# language proposal for default interface methods says:
Interfaces may not contain instance state. While static fields are now permitted, instance fields are not permitted in interfaces. Instance auto-properties are not supported in interfaces, as they would implicitly declare a hidden field.
Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.
Yet another feature is coming with C# 11: static virtual members in interfaces. Those must be implemented by the implementing class. They were primarily introduced to allow formulating interfaces for numeric types who have static operator methods (+, -, *, /, etc.). But they also allow to declare static factory methods. These interfaces are useful in generic type constraints.
Here is a full use case. New properties are added to an interface. To not break existing implementations, they are added with a default implementation.
Since we cannot store instance state in an interface (interfaces are not instantiated), we cannot use instance backing fields for the properties. Instead, we use a dictionary with object references as key to store the property values. (We could also use Weak References, but that's beyond the scope of this article.) The dictionary is stored in a private static field. This is comparable to how WPF stores dependency properties.
interface IUseCase
{
string Name { get; set; } // Public by default, must be implemented by the class
// New property added in a later release with a default implementation.
// Implementation by class is optional.
private static Dictionary<IUseCase, string?> _firstNames =
new(ReferenceEqualityComparer.Instance);
string? FirstName
{
get {
_firstNames.TryGetValue(this, out string? s);
return s; // s is null when TryGetValue returns false
}
set {
_firstNames[this] = value;
}
}
// New property with default implementation.
string FullName => $"{FirstName} {Name}";
}
A class created before the interface was extended implementing only the first property.
class UseCase : IUseCase
{
public UseCase(string name)
{
Name = name;
}
public string Name { get; set; }
}
Test:
IUseCase u1 = new UseCase("Doe");
u1.FirstName = "John";
IUseCase u2 = new UseCase("Poe");
u2.FirstName = "Jane";
Console.WriteLine(u1.FullName);
Console.WriteLine(u2.FullName);
Prints:
John Doe
Jane Poe

It looks like there are two main reasons such as
to store a value that must be shared among all instances
you can count some value between all instances
to avoid recreation of an instance of static field value each time
Let me show a example:
public interface IFoo
{
private static string staticField;
public static string GetStaticField()
{
if (staticField is null)
staticField = $"DateTime is {DateTime.Now}";
return staticField;
}
}
or shorter version will look like this:
public static string GetStaticField()
{
staticField ??= $"DateTime is {DateTime.Now}";
return staticField;
}
and then it can be seen that if staticField will be assigned, then it never be reassigned:
var result_1 = IFoo.GetStaticField();
Console.WriteLine(result_1);
Thread.Sleep(10000); // imitation of hard work
var result_2 = IFoo.GetStaticField();
Console.WriteLine(result_2);
Output:
DateTime is 2022.10.12 05:10
DateTime is 2022.10.12 05:10

Related

What is the best approach or alternative to constant references?

For the purposes of this question, a 'constant reference' is a reference to an object from which you cannot call methods that modify the object or modify it's properties.
I want something like this:
Const<User> user = provider.GetUser(); // Gets a constant reference to an "User" object
var name = user.GetName(); // Ok. Doesn't modify the object
user.SetName("New value"); // <- Error. Shouldn't be able to modify the object
Ideally, I would mark with a custom attribute (e.g. [Constant]) every method of a class that doesn't modify the instance, and only those methods can be called from the constant reference. Calls to other methods would result in an error, if possible, during compile time.
The idea is I can return a read-only reference to and be sure that it will not be modified by the client.
The technique you're referring to is called "const-correctness" which is a language feature of C++ and Swift, but not C#, unfortunately - however you're onto something by using a custom attribute because that way you can enforce it via a Roslyn extension - but that's a rabbit-hole.
Alternatively, there's a much simpler solution using interfaces: because C# (and I think the CLR too) does not support const-correctness (the closest we have is the readonly field modifier) the .NET base-class-library designers added "read-only interfaces" to common mutable types to allow a object (wheather mutable or immutable) to expose its functionality via an interface that only exposes immutable operations. Some examples include IReadOnlyList<T>, IReadOnlyCollection<T>, IReadOnlyDictionary<T> - while these are all enumerable types the technique is good for singular objects too.
This design has the advantage of working in any language that supports interfaces but not const-correctness.
For each type (class, struct, etc) in your project that needs to expose data without risk of being changed - or any immutable operations then create an immutable interface.
Modify your consuming code to use these interfaces instead of the concrete type.
Like so:
Supposing we have a mutable class User and a consuming service:
public class User
{
public String UserName { get; set; }
public Byte[] PasswordHash { get; set; }
public Byte[] PasswordSalt { get; set; }
public Boolean ValidatePassword(String inputPassword)
{
Hash[] inputHash = Crypto.GetHash( inputPassword, this.PasswordSalt );
return Crypto.CompareHashes( this.PasswordHash, inputHash );
}
public void ResetSalt()
{
this.PasswordSalt = Crypto.GetRandomBytes( 16 );
}
}
public static void DoReadOnlyStuffWithUser( User user )
{
...
}
public static void WriteStuffToUser( User user )
{
...
}
Then make an immutable interface:
public interface IReadOnlyUser
{
// Note that the interfaces' properties lack setters.
String UserName { get; }
IReadOnlyList<Byte> PasswordHash { get; }
IReadOnlyList<Byte> PasswordSalt { get; }
// ValidatePassword does not mutate state so it's exposed
Boolean ValidatePassword(String inputPassword);
// But ResetSalt is not exposed because it mutates instance state
}
Then modify your User class and consumers:
public class User : IReadOnlyUser
{
// (same as before, except need to expose IReadOnlyList<Byte> versions of array properties:
IReadOnlyList<Byte> IReadOnlyUser.PasswordHash => this.PasswordHash;
IReadOnlyList<Byte> IReadOnlyUser.PasswordSalt => this.PasswordSalt;
}
public static void DoReadOnlyStuffWithUser( IReadOnlyUser user )
{
...
}
// This method still uses `User` instead of `IReadOnlyUser` because it mutates the instance.
public static void WriteStuffToUser( User user )
{
...
}
So, these are the first two ideas I initially had, but don't quite solve the problem.
Using Dynamic Objects:
The first idea I had was creating a Dynamic Object that would intercept all member invokations and throw an error if the method being called isn't marked with a [Constant] custom attribute. This approach is problematic because a) We don't have the support of the compiler to check for errors in the code (i.e. method name typos) when dealing with dynamic objects, which might lead to a lot of runtime errors; and b) I intend to use this a lot, and searching for method names by name every time a method is called might have considerable performance impact.
Using RealProxy:
My second idea was using a RealProxy to wrap the real object and validate the methods being called, but this only works with objects that inherit from MarshalByRefObject.

Explicit implementation of an interface using a getter-only auto-property (C# 6 feature)

Using automatic properties for explicit interface implementation was not possible in C# 5, but now that C# 6 supports getter-only auto-properties, this should be possible now, right?
Creating the auto-property succeeds in C# 6, but when trying to assign a value to it in the constructor, you have to cast this to the interface type first, since the implementation is explicit. But that's where both VS 2015 RC and VS Code 0.3.0 display the error that can be seen in the comment:
using static System.Console;
namespace ConsoleApp
{
public interface IFoo { string TestFoo { get; } }
public class Impl : IFoo
{
// This was not possible before, but now works.
string IFoo.TestFoo { get; }
public Impl(string value)
{
// ERROR: Property or indexer 'IFoo.TestFoo' cannot be assigned to -- it is read only.
((IFoo)this).TestFoo = value;
}
}
public class Program
{
// Yes, not static. DNX supports that (for constructor DI).
public void Main(string[] args)
{
IFoo foo = new Impl("World");
WriteLine($"Hello {foo.TestFoo}");
ReadKey(true);
}
}
}
Note: I updated the original question that set a constant value to TestFoo. In my real-world scenario, the value comes from an object that is injected into the constructor. The answer by Daniel A. White is excellent if the value returned by the property can be set at initialization.
It says:
Property or indexer 'IFoo.TestFoo' cannot be assigned to -- it is read only.
Is there a way around this, or do I still have to use properties with backing fields for this case?
I am using Visual Studio 2015 RC and Visual Studio Code 0.3.0 with DNX451 1.0.0-beta4.
I have raised an issue over at the Roslyn GitHub page.
The possible duplicate is a question about the definition of an interface with a regular property that can be read. My question is about implementing such an interface explicitly using a new C# 6 feature, that, in theory, should make this possible. See the other question I linked in the first sentence for a similar one (but for C# 5, where getter-only auto-properties where not available yet).
You can get around this by using a read-only backing field for your explicitly implemented property. You can assign the injected value to the backing field within the constructor, the explicit property's get implementation will return it.
public class Impl : IFoo
{
private readonly string _testFoo;
string IFoo.TestFoo => _testFoo;
public Impl(string value)
{
_testFoo = value;
}
}
I think you want this
string IFoo.TestFoo { get; } = "World";

what is the advantage of using private variables in C#

Sample code (alternative code is below),
// person.cs
using System;
class Person
{
private string myName ="N/A";
// Declare a Name property of type string:
public string Name
{
get
{
return myName;
}
set
{
myName = value;
}
}
public override string ToString()
{
return "Name = " + Name;
}
public static void Main()
{
Person person = new Person();
Console.WriteLine("Person details - {0}", person);
person.Name = "Joe";
Console.WriteLine("Person details - {0}", person);
}
}
Can't we directly write, changing myName from private to public, no requirement to declare another public variable Name and no need to use get and set?
alternative code
// person.cs
using System;
class Person
{
public string myName ="N/A";
public override string ToString()
{
return "Name = " + myName;
}
public static void Main()
{
Person person = new Person();
Console.WriteLine("Person details - {0}", person);
person.myName = "Joe";
Console.WriteLine("Person details - {0}", person);
}
}
Externally visible properties are better than fields because:
Properties allow better encapsulation. Fields are a fixed implementation and allow direct access from consumers. Properties:
are loosely coupled (since underlying field can change from variable to
database anytime)
allow custom logic (validation, event notification, lazy loading, etc.)
control access (since logic can be built in get/set, even declared read-only or write-only).
Fields cannot be used in interfaces. This is an impediment to Test Driven Development (interface first).
Automatic or Auto-Implemented Properties are as easy to declare as fields and also optimized to perform on par with fields. See here.
Declaring an externally visible field (public, protected, protected internal) is a FxCop violation. See rule CA1051.
Changing a field to a property is a breaking change, since the calling code needs to be recompiled (applies to binary serialization as well).
Properties are recognized by many libraries in .NET for tasks such as XML serialization, WPF bindings, ASP.NET 2-way binding, etc. and also by Visual Studio designer.
You are cracking up one of the bases of OOP -> information hiding / encapsulation
By defining your properties as public you give EVERYONE access to them and they can be changed (corrupted) as desired. This way you cannot promise that your objects will be in a consistent state all of the time.
From Wikipedia
In programming languages, encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination[1][2] thereof:
- A language mechanism for restricting access to some of the object's components.[3][4]
- A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.[5][6]
Some programming language researchers and academics use the first meaning alone or in combination with the second as a distinguishing feature of object oriented programming, while other programming languages which provide lexical closures view encapsulation as a feature of the language orthogonal to object orientation.
The second definition is motivated by the fact that in many OOP languages hiding of components is not automatic or can be overridden; thus, information hiding is defined as a separate notion by those who prefer the second definition.
In your example there is actually no difference between these 2 approaches. Generally, properties gives you a possibility to make them readonly for other classes (with private setter) - you won't be able to do such thing with the field. Public fields/property setters broke the encapsulation rule of OOP.
In OOP the convention is to hide all your variables from users and use Getters and Setters instead to manipulate with them. There are cases when you will be needing to change variables value until it is saved. For example you prompt user to enter some value that will be velocity and users enter the value in MPH but you want to convert them and store as Km/h or m/s. Now in this case having setter makes sense. There are also cases when you want setter or getter to be private for variable to be read only or write only. But To sum up In OOP Convention is to use setters and getters instead of public variables. This is the part of Encapsulation Concept
You can do, but its not good pratcie. Encapusalting the private varaible as a property means you have greater control in restricting what clients can and can't do
If its seems a little verbose you can also use the following
public string Name { get; set; }
As bash.d wrote this are bases of OOP.
In this Case i would recommend to put the Name in the Constructor:
class Person
{
public Person(string name)
{
this.myName = name;
}
private string myName ="N/A";
public string Name
{
get
{
return myName;
}
private set
{
myName = value;
}
}
public override string ToString()
{
return "Name = " + Name;
}
public static void Main()
{
Person person = new Person("Joe");
Console.WriteLine("Person details - {0}", person);
Console.WriteLine("Person details - {0}", person);
}
}
Other ways use an Method to Set the Value, were you can check the handled object.

Metadata pattern for your object graph

I want to add metadata to my object graph for non-domain type data that will be associated to my objects but is not essential to the problem set of that domain. For example, I need to store sort settings for my objects so that the order in which they appear in the UI is configurable by the user. The sort indices should be serializable so that the objects remember their positions. That's just one among a few other metadata items I need to persist for my objects. My first thought is to solve this by having a MetadataItem and a MetadataItemCollection where the base Entity class will have a "Meta" property of type MetadataItemCollection. E.g.:
public class MetadataItem
{
public string Name;
public object Data;
}
public class MetadataItemCollection
{
/* All normal collection operations here. */
// Implementation-specific interesting ones ...
public object Get(string name);
public MetadataItem GetItem(string name);
// Strongly-type getters ...
public bool GetAsBool(string name);
public string GetAsString(string name);
// ... or could be typed via generics ...
public T Get<T>(string name);
}
public class Entity
{
public MetadataItemCollection Meta { get; }
}
A few concerns I can think of are:
Serialization - the database has a single table of EntityID | Name | Value where Value is a string and all types are serialized to a string?
Future Proofing - what if a metadata item's type (unlikely) or name needs to be changed?
Refactorability - should the keys come from a static list via enum or a class with static string properties, or should free-form strings be allowed:
var i = entity.Meta["SortIndex"];
vs.
public enum Metadatas { SortIndex };
var i = entity.Meta[Metadatas.SortIndex];
vs.
public static class Metadatas
{
public static string SortIndex = "SortIndex";
}
var i = entity.Meta[Metadatas.SortIndex];
Anything else?
Thoughts, ideas, gotchas???
Thanks for your time.
Solution:
Following #Mark's lead, and after watching the Udi video Mark linked to, I created two new interfaces: IUiPresentation and IUiPresentationDataPersistor. It's important to note that none of the objects in my Entity object model have any awareness of these interfaces; the interfaces are in a separate assembly and never referenced by my Entity object model. The magic is then done via IoC in the presentation models. It would be something like the following:
public class PhoneViewModel
{
IUiPresentationDataPersistor<Phone> _uiData
IUiPresentation<Phone> _presenter;
// Let IoC resolve the dependency via ctor injection.
public PhoneViewModel(Phone phone, IUiPresentationDataPersistor<Phone> uiData)
{
_uiData = uiData;
_presenter = uiData.Get(phone); // Does a simple lookup on the phone's ID.
}
public int SortIndex
{
get { return _presenter.SortIndex; }
set { _presenter.SortIndex = value; }
}
public void Save()
{
_uiData.Save();
}
}
It's a little more complicated in that the ViewModel implements INotifyPropertyChanged to get all the goodness that it provides, but this should convey the general idea.
Metadata literally means data about data, but what you seem to be asking for is a way to control and change behavior of your objects.
I think such a concern is much better addressed with a Role Interface - see e.g. Udi Dahan's talk about Making Roles Explicit. More specifically, the Strategy design pattern is used to define loosely coupled behavior. I'd look for a way to combine those two concepts.
As we already know from .NET, the use of static, weakly typed attributes severely limits our options for recomposing components, so I wouldn't go in that direction.

How to implement a read only property

I need to implement a read only property on my type. Moreover the value of this property is going to be set in the constructor and it is not going to be changed (I am writing a class that exposes custom routed UI commands for WPF but it does not matter).
I see two ways to do it:
class MyClass
{
public readonly object MyProperty = new object();
}
class MyClass
{
private readonly object my_property = new object();
public object MyProperty { get { return my_property; } }
}
With all these FxCop errors saying that I should not have public member variables, it seems that the second one is the right way to do it. Is this correct?
Is there any difference between a get only property and a read only member in this case?
The second way is the preferred option.
private readonly int MyVal = 5;
public int MyProp { get { return MyVal;} }
This will ensure that MyVal can only be assigned at initialization (it can also be set in a constructor).
As you had noted - this way you are not exposing an internal member, allowing you to change the internal implementation in the future.
C# 6.0 adds readonly auto properties
public object MyProperty { get; }
So when you don't need to support older compilers you can have a truly readonly property with code that's just as concise as a readonly field.
Versioning:
I think it doesn't make much difference if you are only interested in source compatibility.
Using a property is better for binary compatibility since you can replace it by a property which has a setter without breaking compiled code depending on your library.
Convention:
You are following the convention. In cases like this where the differences between the two possibilities are relatively minor following the convention is better. One case where it might come back to bite you is reflection based code. It might only accept properties and not fields, for example a property editor/viewer.
Serialization
Changing from field to property will probably break a lot of serializers. And AFAIK XmlSerializer does only serialize public properties and not public fields.
Using an Autoproperty
Another common Variation is using an autoproperty with a private setter. While this is short and a property it doesn't enforce the readonlyness. So I prefer the other ones.
Readonly field is selfdocumenting
There is one advantage of the field though:
It makes it clear at a glance at the public interface that it's actually immutable (barring reflection). Whereas in case of a property you can only see that you cannot change it, so you'd have to refer to the documentation or implementation.
But to be honest I use the first one quite often in application code since I'm lazy. In libraries I'm typically more thorough and follow the convention.
With the introduction of C# 6 (in VS 2015), you can now have get-only automatic properties, in which the implicit backing field is readonly (i.e. values can be assigned in the constructor but not elsewhere):
public string Name { get; }
public Customer(string name) // Constructor
{
Name = name;
}
private void SomeFunction()
{
Name = "Something Else"; // Compile-time error
}
And you can now also initialise properties (with or without a setter) inline:
public string Name { get; } = "Boris";
Referring back to the question, this gives you the advantages of option 2 (public member is a property, not a field) with the brevity of option 1.
Unfortunately, it doesn't provide a guarantee of immutability at the level of the public interface (as in #CodesInChaos's point about self-documentation), because to a consumer of the class, having no setter is indistinguishable from having a private setter.
In C# 9, Microsoft introduced a new way to have properties set only on initialization using the init accessor, like so:
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}
This way, you can assign values when initializing a new object:
var person = new Person
{
Firstname = "John",
LastName = "Doe"
}
But later on, you cannot change it:
person.LastName = "Denver"; // throws a compiler error
You can do this:
public int Property { get { ... } private set { ... } }
I agree that the second way is preferable. The only real reason for that preference is the general preference that .NET classes not have public fields. However, if that field is readonly, I can't see how there would be any real objections other than a lack of consistency with other properties. The real difference between a readonly field and get-only property is that the readonly field provides a guarantee that its value will not change over the life of the object and a get-only property does not.
yet another way (my favorite), starting with C# 6
private readonly int MyVal = 5;
public int MyProp => MyVal;
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties#expression-body-definitions
The second method is preferred because of the encapsulation. You can certainly have the readonly field be public, but that goes against C# idioms in which you have data access occur through properties and not fields.
The reasoning behind this is that the property defines a public interface and if the backing implementation to that property changes, you don't end up breaking the rest of the code because the implementation is hidden behind an interface.

Categories

Resources