문제

나는 이것이 공개적으로 더 많은 공개라고 생각하지만 왜 C#을 내 ID 유형을 추론 할 수 없습니까?

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>

다음과 같이 ID로 안내서가있는 정의 된 EntityObject :

public Foo : EntityObject<Guid>

다음과 같이 정의 된 추상 EntityObject 클래스에서 상속 :

public abstract class EntityObject<IdT>
{
    public IdT id { get; set; }
}

Get 메소드의 사용법은 다음과 같습니다.

IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);

추가 설명을 제공하기 위해 편집.

도움이 되었습니까?

해결책

당신이 그것들을 사용하는 방법이 아니라 두 개의 선언 만 주었다고 말하기는 어렵습니다. IDT는 다른 유형 매개 변수가 어딘가에 있습니까? (만약 그렇다면 TId, 그것은 그것을 제안 할 것입니다 - 그러나 당신이 사용하고 있다는 사실은 EntityT 다른 유형 매개 변수의 경우 컨벤션과는 반대로 IdT 마찬가지로 ...)

이제 가정합니다 IdT 실제로입니다 Guid 귀하의 경우, 컴파일러는 어떻게 해야하는지 Foo? 다른 유형이 도출 될 수 있습니다 EntityObject<Guid>.

요컨대, 당신은 우리에게 확실히 말할 수있는 충분한 정보를 제공하지 않았지만, 당신은 기본적으로 컴파일러에 대해 불합리한 요구를하고있는 것처럼 들립니다.

편집 : 좋아, 여기에 당신이 가진 것에 대한 내 추측은 정상적인 명명 규칙을 사용합니다.

public interface IRepository
{
    TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
}

public abstract class EntityObject<TId>
{
    public IdT id { get; set; }
}

public class Foo : EntityObject<Guid> {} 

당신은하고 싶습니다 :

IRepository repository = GetRepositoryFromSomewhere();
Foo foo = repository.Get<Foo>(someGuid);

현재 해야하는 반면 :

Foo foo = repository.Get<Foo, Guid>(someGuid);

예, 컴파일러가 만들고 있습니다 아주 약간 필요한 것보다 더 어렵습니다. 언어를 더 단순하게 유지하고 유형 추론 규칙을 이해하기 쉽게하기 위해 6 개의 추가 캐릭터가 있습니다.

기본적으로 타입 추론은 전부 또는 아무것도 없습니다 - 모두 유형 매개 변수는 추론되거나 그 중 어느 것도 없습니다. 어떤 것이 지정되고 있는지, 그렇지 않은지 알아낼 필요가 없으므로 간단하게 유지합니다. 그것은 문제의 일부이며, 다른 부분은 방법의 유형 매개 변수에만 제약 조건을 표현할 수 있다는 것입니다.

class Repository<TEntity>
{
    TEntity Get<TId>(TId id) where TEntity : EntityObject<TId>
}

그것이 제한적이기 때문입니다 TEntity, 아니다 TId. 다시 말하지만, 이런 종류의 것은 유형의 추론을 더 간단하게 만듭니다.

이제 당신 ~할 수 있었다 잠재적으로 쓰기 :

Foo foo = repository.Get(someGuid).For<Foo>();

적절한 Get 방법 및 추가 인터페이스. 나는 개인적으로 그냥 사용하는 것을 선호한다고 생각합니다 Get<Foo, Guid> 그렇지만.

다른 팁

선언과 같은 선언

public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>

IDT는 구체적인 유형이라는 요구를 요구합니다. IDT를 매개 변수화하려면 사용해야합니다.

public EntityT Get<EntityT, IdT>(IdT id) where EntityT : EntityObject<IdT>

그러나 그것은 아마도 당신이 원하는 것이 아닐 것입니다.

이것이 제가 일반 개체와 함께 일반적인 키 유형을 포기한 이유입니다. 나는 내 엔티티가 두 곳에 두 개를 뿌리지 않고 일반적인 키 유형을 갖도록하는 방법을 알 수 없었습니다. 이제 나는 정수 키에 정착했지만 (어쨌든 내가 가진 곳) 잘못 느껴집니다.

메소드 서명이 다음과 같이 보인 경우 :

public TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>

컴파일러는 작업 할 것이 있습니다 ...

그런 다음 다음과 같은 것을 호출합니다.

편집 (나는 틀렸다) : 제품 p = get (id);

Product p = Get<Product, Guid>(id);

Jon은 그의 게시물 위로이 답을 못 박 았으므로 내 구멍에서 닥치고 기어 올랐습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top