Replies: 12 comments 2 replies
-
This looks like a duplicate of #1294, only with different syntax. |
Beta Was this translation helpful? Give feedback.
-
This proposal adds the ability to reference the other type in generic type arguments as well. I wonder if associated types would satisfy that use case. |
Beta Was this translation helpful? Give feedback.
-
Yeah it seems alike it will look at the existing |
Beta Was this translation helpful? Give feedback.
-
I'm not sure exactly, public interface IGenericInterface<TDesiredType> {
public TDesiredType DesiredProperty {get;set;}
} we can hope to have this: public interafce IInheritedInterface : IGenericInterface<int>{
}
and
public interface UseInterface<useType(IInheritedInterface.DesiredProperty)>{ //1
public useType(IInheritedInterface.DesiredProperty) Data{get;set;} //2
} but not this: public interface INotAllowed<useType(IGenericInterface.DesiredProperty)>{} this should generate an error such as:
or
still it should be allowed if: we are referencing an instance : public class InheritedClass:InheritedInterface{}
InheritedClass newInstance = new InheritedClass();
var instance = (IGenericInterface)newInstance;
useType(instance.DesiredProperty) variable = instance.DesiredProperty; Also it can be expanded to method too.
|
Beta Was this translation helpful? Give feedback.
-
I think what you want should be #1695 . |
Beta Was this translation helpful? Give feedback.
-
I don't feel like it, it seem to serve some of the purposes but in term of adding additional complexity to the reader. although #1695 is nice feature to have, it's a bit off toward the topic I'm talking about, |
Beta Was this translation helpful? Give feedback.
-
I like the idea. TypeScript, for example, has the feature. I think, though, that the |
Beta Was this translation helpful? Give feedback.
-
I like it, but with a better name: useTypeOf([source member]). Consider the next usual business example:
This would avoid a lot of type mismatch exceptions. |
Beta Was this translation helpful? Give feedback.
-
the name is not an issue to me, but exactly it's too keep related stuff in sync, and also make intellisense and refactoring smarter |
Beta Was this translation helpful? Give feedback.
-
I saw some people gave this feature thumbs down,... I wish to discuss why you think this feature is bad. and compare it's cons vs its pros |
Beta Was this translation helpful? Give feedback.
-
Well, since you asked nicely. 😁 Apologies for the wall of text, this went longer than I expected. 1. The motivating example isn't compelling Of all of the dozens of systems I've worked on, and the uncountable other systems (many hundreds) that I've discussed with people over my career, I'm only aware of one system that actually changed the type used for their database identifiers. For that system, they had used a 32-bit integer as their primary key and were fast closing in on two billion records in a core table, necessitating a rapid pivot. Changing the underlying data type was the least of their problems, and a mechanical approach to doing so would only have created problems as every piece of code needed to be carefully reviewd, modified, and tested. In fact, given that they can't afford any downtime at all, I strongly suspect they would have introduced the second identifier alongside the existing one, with both coexisting for a time as different components were completed and released. (This is conjecture on my part, however.) 2. There are already good patterns for solving this problem that don't require language support While it's commonly done, there are serious issues with using int or long as a unique identifier. Those types have a lot of functionality that's irellevant to the use - it doesn't make sense to calcuate Same applies to the use of string - why would Using primitive types for unique identifiers is easy, convenient, commonplace, pervasive, and ultimately error prone. Defining a custom struct type for an identifier is a simple, straightforward exercise that not only avoids the problems caused by use of primitive types but makes this proposed language feature irellevant. For example, here's a public struct TimeSeriesId : IEquatable<TimeSeriesId>
{
private readonly string _id;
public TimeSeriesId(string id)
=> _id = IsValidId(id)
? id
: throw new ArgumentNullException(nameof(id));
public static bool IsValidId(string id)
=> !string.IsNullOrWhiteSpace(id);
public bool Equals(TimeSeriesId id)
=> string.Equals(_id, id._id, StringComparison.OrdinalIgnoreCase);
public override bool Equals(object obj)
=> obj is TimeSeriesId id && Equals(id);
public override int GetHashCode()
=> StringComparer.OrdinalIgnoreCase.GetHashCode(_id);
} 3. Poor return on investment for the Language Team The C# Language team has limited time and resources (Microsoft might be a very large company, but it also has a very large portfolio of products); the actual number of people working on C# is surprisingly small. Given this, they need to prioritize their efforts - and we can see from recent history the kinds of changes that make it across the finishing line. Expression bodied members (methods, getters and setters) only provide a minor benefit each time they're used, but they're used so often that the overall total becomes quite significant. My guess is that their implementation was relatively simple. The async and await contextual keywords provide enormous value whe used, because they make asyncronous programming accessible to us mere mortals. While the feature was difficult (and therefore expensive) to implement, the benefit when used is substantial, especially as concurrency becomes a mainstay of high performance computing. Recently introduced, the half floating point type is very targetted; most people will never need/want it - but for those who do, it's value is high. I believe that a usetype keyword would be challenging (and therefore expensive) to implement in the compiler (mostly due to edge cases such as chained use, generics, reference assmblies, and binary compatibility), but the benefit to the wider C# would be limited. Given that there are already good ways to solve this problem that don't require new language support, I don't believe this would be a good use of the teams time. |
Beta Was this translation helpful? Give feedback.
-
@deadmann I also currently downvoted. And since you asked, here are some of my initial thoughts:
public interface IA<T> { public T a { get; } }
public class A<T> : IA<useType(IA<C>.a)> { }
public class B<T> : IA<useType(IA<useType(IA<useType(IA<useType(IA<useType(IA<C>.a)>.a)>.a)>.a)>.a)> { } I'm sure I would have more thoughts if I gave it further thought, but this just seems like a bad idea. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Today with so many architect, lot of stuff rely on each other, and some of them are repeated, and changing them requires lot of changes,... what I'm going to say may have many usage through time, but I came up with it when i was working on repository interface...
Here's the scenario:
I have a class
and then I have a base repository
and then I have a repository for that class
the issue here is if I get to change that entity ID type to say long, I have to update all interfaces and repository of that type too, aside from any layer that may been built upon it.
So I suggest a new feature "useType", i rather name it typeof, but it's already in use and as suggested it returns a Type object, so here i named it useType, or anything that came to mind with better understanding
and then, I suggest to rewrite the XRepository as following
It also can simplify and come to aid, in many other scenario, when you need to use a type directly with generics, with reflections, within many other things out there.
Beta Was this translation helpful? Give feedback.
All reactions