Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign a value to an explicitly-implemented readonly interface property in a constructor

Tags:

c#

.net

c#-7.0

Same question as this one, but for C# 7.0 instead of 6.0:

Is there a way to assign a value to an explicitly-implemented read-only (getter only) interface property in a constructor? Or is it still the same answer, i.e. use the backing-field work-around?

For example:

interface IPerson
{
    string Name { get; }
}

class MyPerson : IPerson
{
    string IPerson.Name { get; }

    internal MyPerson(string withName)
    {
        // doesn't work; Property or indexer 'IPerson.Name' 
        // cannot be assigned to --it is read only
        ((IPerson)this).Name = withName; 
    }
}

Work-around:

class MyPerson : IPerson
{
    string _name;
    string IPerson.Name { get { return _name; } }

    internal MyPerson(string withName)
    {
        _name = withName; 
    }
}
like image 676
rory.ap Avatar asked Jun 09 '17 17:06

rory.ap


People also ask

CAN interface have constructor in C#?

Interfaces can contain properties and methods, but not fields/variables. Interface members are by default abstract and public. An interface cannot contain a constructor (as it cannot be used to create objects)

Can I inherit property from class to interface?

A class implements an interface, it does not inherit it.

How do you call an interface method in C#?

In order to call the methods using interface reference(here r is interface reference), you have to assign to class object to it. Like if you are assigning Person1's object obj1 to r i.e. r = obj1; then you call the Speed() and Distance() methods that are implemented by the Person1 class.


1 Answers

As of C# 7, the best you can do is to take advantage of expression-bodied properties and constructors to slightly simplify your code:

class MyPerson : IPerson
{
    string _name;
    string IPerson.Name => _name;

    internal MyPerson(string withName) => _name = withName;
}

This doesn't directly address your question though: having a means of setting an interface-explicit property from the constructor. There is a proposal though that might address this in the future, but there are no guarantees.

Proposal: Property-Scoped Fields, which suggests allowing the contextual keyword field to be used within properties to refer to the backing field, without having to explicitly define the latter. It's possible that this might also provide syntax along the lines of:

string IPerson.Name { get; }
internal MyPerson(string withName) => IPerson.Name.field = withName;

However, the above link is to just a discussion topic on the C# language repo on GitHub. I hasn't (yet) been "championed" by the language team, which is the first step to it even being considered as a new feature. so the odds are this will never be added to the language (but things defy the odds sometimes, so never say never...)

like image 147
David Arno Avatar answered Sep 28 '22 04:09

David Arno