Replies: 15 comments 6 replies
-
IMHO it has nothing to do with interface. For example, how compiler have to choose between different constructors? Meanwhile, public static IEnumerable<int> CreateRandomData<R>(int length) where R : IRandom, new(int) seems to be far more reasonable. And in this case IRandom is optional. For example: public static IEnumerable<R> CreateRandomData<R>(int length) where R : new(int)
{
var randomGenerator = new Random(50);
for (int i = 0; i < length; i++)
yield return new R(randomGenerator.Next());
} |
Beta Was this translation helpful? Give feedback.
-
In the typical case, classes implementing the same interface nevertheless need different parameters in their constructors.
Having a predefined constructor signature would require squeezing the parameters into the signature types, which isn't going to produce a good code. Let's not endorse bad coding patterns. |
Beta Was this translation helpful? Give feedback.
-
Most obvious and direct solution is to use "factory pattern". Just define "factory interface" public interface ISomething
{
// ...
}
public interface ISomethingFactory<T> where T : ISomething
{
T Create(int arg1, string arg2);
} |
Beta Was this translation helpful? Give feedback.
-
What does this gain you over simply declaring a separate factory interface or custom delegate? Plus, like @vladd says there's the problem of different implementations needing extra constructor parameters which is almost a given. |
Beta Was this translation helpful? Give feedback.
-
@jnm2 C# is a turing-complete language so you already can express anything, but it's better to have a language support than write factory of factory of adapter of facade. You wrote an entire factory just to invoke a constructor. It's a completly mechanical process and this is what compilers are good at. |
Beta Was this translation helpful? Give feedback.
-
@jnm2 it's the same kind of request as the one about async constructors (#419). In both cases you can use a factory method, but bare factory methods are an antipattern in my opinion. You should construct objects using constructors, and it's an unnecessary limitation of the language that a constructor is a special method that always automatically allocates a new object. I would gladly welcome constructors that return cached instances, construct objects asynchronously etc. Why can't the rules of object instantiation be a part of the interface? They are no different from the rules of interaction. |
Beta Was this translation helpful? Give feedback.
-
Constructors aren't virtual and aren't inherited behavior. It generally doesn't make any sense for them to be given each type has very different dependencies. That said, I would imagine that shapes would satisfy this proposal. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour constructors has defenitly inherited behaviour. It has been discussed already: #419 (comment) and dotnet/roslyn#6788 (comment) . I didn't invent any worthwhile solution but I defenitly think that we need more asyncish support in language and it's possible, but just not this obvious that it can be easily found. Anyway, it's beside the point and proposed issue. |
Beta Was this translation helpful? Give feedback.
-
What you are describing is not inheritance. Constructors are not inherited, which is why a derived class must invoke a parent constructor from its own constructor. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour In this regard you're right, because I meant logical "inheritance". |
Beta Was this translation helpful? Give feedback.
-
I subscribe to the view that the need for a design pattern in code is an indication of a deficit in that language. Factory patterns are one such example. As @orthoxerox says, However, I do not see this proposal as addressing any of this. What parameters a class needs for its constructors is implementation specific. Binding all implementations to a specific constructor defined by an interface feels like a step in the wrong direction to me. |
Beta Was this translation helpful? Give feedback.
-
Another downside is that it may encourage people to use it for logic classes forcing either to "service-locate" dependencies or to avoid DI all together (although it is not a good argument not to add features, see local functions...). Perhaps we could solve this in a different fashion, as having to write a factory to achieve this is of course good practice, but a lot of boilerplate in simple cases. User could rely on high order functions passing the factory method in, but that would make it even closer to the implementation in some cases. |
Beta Was this translation helpful? Give feedback.
-
I don't understand why you'd ever expect to be able to return arbitrary objects from a constructor. We need the concept of construction. It's unique; it means "build a brand new instance." You can't replace it with a higher-level factory abstraction. Any factory abstraction would have to delegate back to construction at some point so the factory abstraction itself wouldn't be called "construction." |
Beta Was this translation helpful? Give feedback.
-
I'm not sure we would expect to. |
Beta Was this translation helpful? Give feedback.
-
#164 should solve this problem. |
Beta Was this translation helpful? Give feedback.
-
I was looking at this proposal from @devedse : #769
And it would be a nice language feature although, I agree with @jnm2 on his comment: #769 (comment) about the lack of semantical meaning
How about defining the constructor on the interfaces? That would solve both problems; it will allow parameters in constructors and the interface can specify the meaning with named parameters and a constructor that is bound to the interface meaning itself.
Haven't thought this through yet so please apologise if it has some evident pitfall.
For instance, I, for one, struggle with the idea of forcing a parameter on an interface that has potentially no effect on the public API output but it is just an internal implementation detail.
Beta Was this translation helpful? Give feedback.
All reactions