1

Would it be useful define a type in C# that defines something similar to a data table so it can be instantiated but may not contain logic and also act as an interface?

In addition I'm thinking this could be used in place/in addition to interfaces.

record A
{
    string S { get; set; }
}

could be "syntactic sugar" for

interface A
{
    string S { get; set; }
}
class A : A
{
    public string S { get; set; }
}

Of course there's a name collision here. That's why it would need to be a language level feature (as opposed to something that could be done with a T4 template for example).

One could instantiate A. One could implement A. If there were B and C, then one could implement all three.

My intuition is that this would not be sufficient to bring the down side of multiple inheritance but may open up implementation patterns which would be cleaner and few lines.

Here's one Example of not needing to define the interface and the reason I like the separation of data and functions is because I'm thinking of generic repositories that model the real world and separate libraries of functions that act on them...

// records exist as pure domain objects, possibly even standardized
record Entity
{
    public string FullName { get; set; }
}
record Dimensions
{
    public float Length { get; set; }
    public float Width { get; set; }
    public float Height { get; set; }
}
class Person : Entity, Dimensions
{
    // tooling is used to generate these members
    // name collisions are resolved using explicit member declaration
    public string FullName { get; set; }
    public float Length { get; set; }
    public float Width { get; set; }
    public float Height { get; set; }
}
static class Extensions
{
    public static void GetNameParts(this Entity target, out string first, out string last)
    {
        first = "todo";
        last = "todo";
    }

    public static float CalculateVolume(this Dimensions target)
    {
        return target.Length * target.Width * target.Height;
    }
}

Update: "Partial-Assignment" might also be useful:

var entity = new Entity { FullName = "Jim Bob" };
var person = new Person { Entity = entity }; // Entity exists implicitly in this context

The implicit property with the same name as the inherited record is also used to easily access members which may have the same names but come from different types.

7
  • 2
    I don't see what advantage this would bring. Could you give an example of an "implementation pattern" this would be used for?
    – Caleb
    Commented Aug 5, 2015 at 0:25
  • It is insufficient to do multiple inheritance since the properties still have backing.
    – Telastyn
    Commented Aug 5, 2015 at 1:01
  • A propos name collisions, your proposed name for this feature clashes with the existing proposal for records, although both syntax and semantics are different. Commented Aug 5, 2015 at 15:22
  • Basically. Would there be room in c# for a type of class-like type that behaves like a mix between interfaces and classes; which may only contain auto-properties and may also be inherited like multiple interfaces can.
    – mausworks
    Commented Aug 6, 2015 at 21:45
  • or alternately, simply allow classes which consist only of auto-properties to be inherited like multiple interfaces can.. Commented Aug 6, 2015 at 22:44

1 Answer 1

3

I think i understand OPs question (it was somewhat vague at first).
Although now, I'm not so sure, after reading it again a few times.


The question (as i understand it) summarized:

Is there room in C# for a interface-like construct (proposed name: record), which may only contain auto-properties, but also has the advantages of an interface in where a class can inherit multiple of these "records" at once.

OPs design example:

Records:

record Entity
{
    public string FullName { get; set; }
}
record Dimensions
{
    public float Length { get; set; }
    public float Width { get; set; }
    public float Height { get; set; }
}

A class implementing the two records
I'm guessing that these properties are actually "not visible" in the class (and are just described by OP)

class Person : Entity, Dimensions
{
    public string FullName { get; set; }
    public float Length { get; set; }
    public float Width { get; set; }
    public float Height { get; set; }
}

Extensions for Entity.

static class Extensions
{
    public static void GetNameParts(this Entity target, out string first, out string last)
    {
        first = "todo";
        last = "todo";
    }

    public static float CalculateVolume(this Dimensions target)
    {
        return target.Length * target.Width * target.Height;
    }
}

Background

At one point i was somewhat annoyed that interface-properties were not "automatic", that you always had to be manually implemented the properties you had already written in your interface, in your then later derived classes.

I was also annoyed that derived classes only could inherit one class at the time.

This created the perfect annoyance where one could no "lazily" implement multiple interfaces or classes.

Solution

This is the solution I have realized, and I find it's working for me. I'm not claiming it's "the correct one".

Grit your teeth, and use more abstraction. Create "common" abstract (or concrete) classes that are "half way there". For instance.

You have the following interfaces

  • IEntity - base interface for all database-entities
  • ILinkable- defines that the entity can be visited vi a URL
  • IInFolder - defines that the entity is in a folder
  • ILoggedEntity - defines that the entity has creation and edited-dates.

You can then create an abstract class which implements these, as such:

public abstract class Article : IEntity, ILinkable, IInFolder, ILoggedEntity
{
    public Guid Id { get; set; } // From IEntity
    public DateTime Created { get; set; } // From ILoggedEntity
    public DateTime Edited { get; set; } // From ILoggedEntity
    public string Url { get; set; } // From ILinkable
    public Folder Folder { get; set; } // From IInFolder
}

Entities like Page, Product, Picture, File etc... can all inherit Article which saves loads of effort, and is generally considered a good design-pattern.

Usually it doesn't start out with the creation of these abstract half-way-there-classes. It's often a matter of going back through the code and refactoring where "common patterns" occur. — At least that's my experience. I guess it also depends on how your specific company designs your software, if there is an elaborate design phase where class-diagrams and similar are made. Then i guess these things are realized before the coding-phase has begun.

— But back to the question at hand.

Is there room in C# for a "record"-construct?

I'm not a language-designer, these are just my thoughts.

The described record-construct would be kind of nice, I'm not gonna lie. But the only problem is, it really only solves a "minor annoyance", it doesn't really add much functionality to the language. Interfaces still get the job done nicely.

Ultimately though; isn't programming supposed to be as comfortable as possible? Writing extra lines of code takes time. Time costs money; both for your clients and you.

So it boils down to

- The proposed construct does not add much (if any) functionality
+ The proposed construct could for some purposes save time and effort.

But it also boils down to how hard it is to implement

Implementation

I honestly don't think it would be very hard to implement. Most of the implementation could be solved via compiler magic. There's already loads of it in C#. Because there would be no need to create a new construct within the compiler. The compiler could simply treat record as an alias for interface; and the properties (if not defined in the derived class) would be implemented as auto-properties.

Is it worth implementing?

In my opinion? — Absolutely.
But maybe not in the proposed form.

But i think a new keyword, such as auto or concrete would be more suitable within the context of an interface, or even re-use any of the other keywords.

Here's an example:

public interface ILinkable
{
    auto string Url { get; set; }
}

Will it be implemented?

Most likely! I'm not saying it will be implemented in Microsofts "official" C#-compiler (not anytime soon at least). But Roslyn seems to be here to stay. If you have not heard of Roslyn (you have missed out), it's basically an open source C#-compiler written in C#. And is now considered stable.

... Roslyn was RTMed with visual studio 2015.

Which i was unaware of, so start you could attempt to implement something like this yourself.
Even if not you, chances are pretty great that somebody (remember you can be somebody) is going to implement something similar to what both you and I have described.

1
  • I'm not entirely up to date it seems. Will update.
    – mausworks
    Commented Aug 7, 2015 at 7:34

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.