2016-04-18 9 views
2

Typ eingeben Ich habe eine Schnittstelle gemacht, so dass ich versuchen kann, einige generische Code wiederholen.Warum kann Inferenz Typ nicht von Constraints

public interface IIdentifiable<T> 
{ 
    T Id { get; set; } 
} 

Dann habe ich eine Klasse, die mit einem Unternehmen arbeitet, mit der Einschränkung von IIdentifiable<T>

public class MyClass<TEntity, TId> 
    where TEntity : IIdentifiable<TId> {} 

Aber jetzt, wenn ich MyClass verwenden Ich habe in TId sogar passieren, obwohl es nur einen gültigen Typ ist für TId.

public class MyEntity : IIdentifiable<Guid> {} 

var foo = new MyClass<MyEntity>(); // Error 
var bar = new MyClass<MyEntity, Guid>(); 

In C++ Ich kann dies tun:

template<typename T> 
struct IIdentifiable 
{ 
    using id_type = T; 

    T id; 
}; 

template<typename TEntity, typename TId = typename TEntity::id_type> 
struct MyClass {}; 

MyClass<MyEntity> foo; 

Gibt es eine C# -Äquivalent?

+0

Ich bin mir nicht sicher, was Sie mit 'MyClass' machen wollen - es verwendet' TEntity' nirgends. –

+0

@MatthewWatson Ich habe es für die Frage vereinfacht, aber in meinem Anwendungsfall nimmt der Konstruktor eine 'TEntity'. – maddisoj

+0

@maddisoj In einigen Fällen können Sie mit einer Fabrikmethode arbeiten, indem Sie Typinterferenzen nutzen. Sie könnten jedoch davon profitieren, uns zu sagen, wie Sie diese Schnittstellen verwenden würden. So können wir Sie auf eine geeignete Lösung hinweisen, siehe [Was ist das XY-Problem? ?] (http://meta.stackexchange.com/q/66377/271659). –

Antwort

5

es nur einen gültigen Typ für TId

Falsch! :)

Counterexample:

public class MyEntity : IIdentifiable<Guid> 
{ 
    public Guid Id { get; set; } 
} 

public class MyOtherEntity : MyEntity, IIdentifiable<int> 
{ 
    int IIdentifiable<int>.Id { get; set; } 
} 

var foo = new MyClass<MyOtherEntity>(); // So, which IIdentifiable should be used? 

Außerdem C# Generika funktionieren nicht wie C++ Vorlagen, sind sie zur Laufzeit verdinglicht und haben unterschiedliche Einschränkungen.

+0

Nun ja, wenn Sie andere gültige Typen hinzufügen, gibt es andere gültige Typen. Im ursprünglichen Fall gibt es nur einen gültigen Typ ... – Rawling

+1

@Rawling, außer dass es zur Laufzeit nur einen gültigen Typ geben muss. Bei dynamisch ladbaren Klassen ist das nicht so einfach. Die 'where'-Einschränkung bedeutet * ist-a *, nicht * ist-genau-a *. –

+0

'MyClass' ist zur Kompilierzeit bekannt; Wenn es nur eine gültige 'Identifizierbare' Implementierung hat, kann es dann zur Laufzeit noch eine andere gewinnen? – Rawling

Verwandte Themen