public class MyClass : ISelfReferenceable<Guid>
{
public Guid Id {get;set;}
public Guid? ParentId {get;set;}
}
public interface ISelfReferenceable<TId>
{
TId Id {get;set;}
TId? ParentId {get;set;}
}
Может ли кто-нибудь объяснить мне, почему вышеперечисленное не работает?
Он кричит Ошибка компилятора CS0738
'type name' does not implement interface member 'member name'. 'method name' cannot implement 'interface member' because it does not have the matching return type of ' type name'.
на MyClass.ParentId
, говоря, что это не реализует ISelfReferenceable.ParentId
, если я не изменю MyClass.ParentId
с Guid?
на Guid
.
В настоящее время я обхожу это, используя два универсальных типа, один для Id
, а другой для ParentId
, или просто делаю ParentId
Guid
вместо Guid?
.
Это правильный подход и есть ли лучший способ сделать это?
Я не знаю, подходит ли это для вашей цели, но оно компилируется следующим образом:
public interface ISelfReferenceable<TId> where TId : struct
{
TId Id {get;set;}
TId? ParentId {get;set;}
}
Помните, что Guid
— это тип значения.
Проблема в том, что TId?
интерпретируется как обнуляемый ссылочный тип (на самом деле это сложнее и зависит от языковой версии и от того, находитесь ли вы в контексте, допускающем значение NULL. См. также объяснение в разделе ограничение по умолчанию). Вы можете исправить это, добавив в интерфейс ограничение универсального типа where TId : struct
. Но, конечно, это ограничивает применимые типы только типами значений. string
Идентификатор был бы невозможен.
Ошибка также исчезнет, если вы объявите
public class MyClass : ISelfReferenceable<string>
{
public string Id { get; set; }
public string? ParentId { get; set; }
}