Proposal: member-typing #2919
Replies: 14 comments
-
What problem are you trying to solve with that? |
Beta Was this translation helpful? Give feedback.
-
The idea seems to be that "MyClass.Id" as used in the Dictionary would effectively be "string," but would be checked to ensure that it is only assigned to/from that one specific source, and also inherently mirrors the type should it change. I can't find the correct issues but it's similar to previous discussions on compile-time checked type aliases. |
Beta Was this translation helpful? Give feedback.
-
Far better to solve this using features that are already present in the language: using System.Collections.Generic;
class Person
{
public PersonId Id { get; private set; }
static void Main()
{
var dict = new Dictionary<PersonId, Person>();
var my = new Person { Id = "0" };
dict.Add(my.Id, my);
}
}
struct PersonId { ... } For one, a struct or class called
|
Beta Was this translation helpful? Give feedback.
-
What you actually want might be |
Beta Was this translation helpful? Give feedback.
-
@Thaina that doesn't allow you to look up an item by id, only to deduplicate |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h That's right I forgot So maybe what the OP really need is a custom class that just wrap a |
Beta Was this translation helpful? Give feedback.
-
Wrapping the string value would add at least this much boilerplate for each type of string: public struct PersonId
{
public string? Value { get; set; }
public static implicit operator string?(PersonId personId) => personId.Value;
public static implicit operator PersonId(string? value) => new PersonId { Value = value };
public override bool Equals(object? obj) => obj is PersonId id && Value == id.Value;
public override int GetHashCode() => HashCode.Combine(Value);
public static bool operator ==(PersonId left, PersonId right) => left.Equals(right);
public static bool operator !=(PersonId left, PersonId right) => !(left == right);
} I think it would be nice if we can easily clone struct's type definition just like how we derive classes: // Deriving classes
class Foo : Bar { }
// Cloning structs
struct Foo : string; |
Beta Was this translation helpful? Give feedback.
-
Intention is to achieve better type safety by "attaching" the rules to the location. As in Bevan's example above, the same can be achieved with existing tools (by defining However, it requires introducing type for each property (you can rarely find a property which type exactly matches the underlying type), and, since each piece of code by-itself introduces a space for bugs, in many cases it is simply not worth the effort. Especially, when adding a new property, it is very attractive to re-use an existing type: class Person
{
public PersonId Id { get; private set; }
public PersonId ParentId { get; private set; }
static void Populate()
{
var me = new Person { Id = "0", ParentId = "4" };
var peopleByIds = new Dictionary<PersonId, Person>();
var peopleByParentIds = new Dictionary<PersonId, Person>();
peopleByIds.Add(me.Id, me);
// bug
peopleByParentIds.Add(me.Id, me);
// ...
}
} Of course, introducing |
Beta Was this translation helpful? Give feedback.
-
Another, secondary point is a performance. In the example above we're allocating an additional object ( This can be avoided with automatic property types, which can be replaced with underlying property times at compile-time. |
Beta Was this translation helpful? Give feedback.
-
@astef |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h It will require an allocation once it leaves stack (when you add it to dictionary). Check this out: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing |
Beta Was this translation helpful? Give feedback.
-
Dictionaries don't box as they are generic. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt oops, yes, sorry for my blindness. The allocation will still be in place, but in case with structs, it looks like there will be no overhead compared to a single field. |
Beta Was this translation helpful? Give feedback.
-
FWIW this is a feature of Typescript that I really like: Given a type type Person = {
name: string,
dob: Date
} I want to create a let people: Map<string, Person> = new Map() I can then create a let alex : Person = { name: "Alex", dob: new Date("2000-1-1") }
people.set(alex.name, alex) This works fine, but it's actually both more descriptive and refactoring safe if I define the map like so: let people: Map<Person["name"], Person> = new Map() So, in principal, I support adding something like this to C#. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Generate a separate special type for each public member. This type should be assignable to a property type.
This small sample shows it all:
Beta Was this translation helpful? Give feedback.
All reactions