-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Type Interfaces #2427
Comments
Sounds very Delphi. The problem is as you described. Each defined runtime type isn't it's own class, as they are in Delphi. As such there is nothing to implement the interface or to own the vtable necessary for virtual dispatch or overriding in child types. Generally the answer to this request is to use factory interfaces instead of relying on static methods to implement factories. |
The problem with factories is that at some point I still either need to reference each type explicitly or use reflection to create each type in an unsafe way. |
There's no need for reflection and you can still reference the types generically, you just need to implement these services as instance methods rather than static methods. public interface ITestTypeInterface { }
public interface ITestTypeFactoryInterface<T> where T : ITestTypeInterface {
string Title { get; }
void DoSomething();
T Create(int value);
}
public class TestGeneric<TF, T>
where TF : ITestTypeFactoryInterface<T>, new ()
where T : ITestTypeInterface
{
public T Instance { get; private set; }
public TestGeneric() {
TF factory = new TF();
Console.WriteLine(factory.Title);
factory.DoSomething();
Instance = factory.Create(12);
}
} |
This only covers the case within a generic. If I'm instantiating objects via reflection (which is the case I'm more concerned about) I still have the same issue. Either I have to create my object unsafely, or I have to create my factory unsafely. Also, this doesn't allow me to get information from the type (like title or description) unless I put this data into the factory. I mentioned a use case for this in my original post. |
Well, dealing with reflection something is going to be unsafe either way. But it's the same problem, at some point something is created unsafely, whether that be a factory instance, or some kind of proxy class pretending to be a runtime type that is serving as a factory instance. C# could probably just fake it just like Oxygene does (Delphi for .NET) but it won't be of nearly the same value as it is in Delphi given that any type's static methods can be accessed through an instance of it's type. Anywho I'd be curious to get a C# language designers take on this. If Anders really found it useful I imagine that it would've been on the drawing board early on. |
I'm not sure what you are saying. There wouldn't be anything unsafe about it if you can access the statics as instance members on the type (as I was suggesting). You cast it to the interface and then all property and functions calls (and constructor calls) on that type would be checked at compile time. |
Taken to its logical conclusion, complete with CLR changes, sure. And there are a few other issues in here for many of those exact features (static method generic constraints, static members in interfaces, #2402 ctors in interfaces). Not saying that I disagree with the concept. I can think of several places in my code where it could've been useful. This is also actually a dupe of #2204. |
Issue #2204 doesn't include the reflection stuff. Static interfaces for constraints is great (and would allow me to be sure my reflection calls will succeed), but it still leaves me with unsafe code when creating objects through reflection. |
Doesn't mention it directly but it would need the same metaclass concept to function. Your reflection scenario effectively requires that metaclasses become a first class citizen in the CLR otherwise |
I agree that the core concept is the same, but the additional use case I'm proposing could have a significant impact on implementation. |
This is a dup of #154. |
You could also call this a static interface, because what it would allow you to do is enforce the implementation of constructors and static methods (similar to Issue #154). I'm calling it a Type interface, because the runtime type object would actually be the one that implements the interface. For example:
This class could then be used as follows:
Using this as a constraint for Generics is fairly straight forward, but I think its use for reflection is more interesting:
This would be possible if the type object for test class looked something like this:
This interface would both enforce that certain statics be implemented in a class, and expose them as instance members on the type object. This second point is critical, as it would allow for significantly more type-safe work with reflection.
As an example use case, in an application I work on we have a list of views for modifying settings. I construct this list dynamically using reflection. Currently I have to count on certain static properties existing to get the title, and description (I could use attributes, but their presence still could not be enforced at compile time), and I have to use Activator.CreateInstance to instantiate instances. This feature would allow me to do all of this in a concrete and type-safe fashion. In addition to the more obvious relevance to Generics (as shown above), this feature would make dynamically composing an application via reflection way safer.
I understand that the interfaces on Types concept would involve significant CLR changes (maybe this isn't even really possible), but I hope I got across what it is I would like to be able to do. Maybe there is another way to accomplish this type safety within reflection. What are your thoughts?
The text was updated successfully, but these errors were encountered: