2017-11-06 3 views
0

작은 문제가있어서 제대로 작동하지 않는 것 같습니다.C# 상속을 받더라도 인터페이스에 캐스트 할 수 없습니다.

public class ModelConverterList : List<IModelConverter<IDataCollection>> 
{ 
} 

그리고이 같은 항목을 추가하려고 : 나는 현재 같은 IModelConverters의 목록을 가지고

public static void AddModelConverter<T>(IModelConverter<T> converter) 
    where T: IDataCollection 
{ 
    CheckForSetup(); 
    modelConverters.Add(converter); 
} 

CheckForSetup 목록 일부와 함께 (null가 아닌 경우 확인하는 방법입니다 기타 무관 한 검사).

public interface IModelConverter<in T>: IConverter where T: IDataCollection 
{ 
    ResponseData Activate(T documents, ServiceContext services, bool overrideIfNeeded = false); 

    bool ContainsFile(T document, ServiceContext services); 
} 

그러나,이 인터페이스로 캐스팅하지 않습니다 이것은 내가 캐스팅하고자하는 인터페이스입니다. 나는 그것을 캐스팅하려고 시도했다. IModelConverter<T>IModelConverter<IDataCollection>

내가 추가하고 싶은 객체는 인터페이스를 사용하는 추상 클래스를 가지고 있는데, 이것이 왜 작동하지 않을 수 있겠는가?

나는 또한 그것에 대한 다중 참조를 생각했지만 그럴 듯하지는 않습니다.

편집 :

내가 편집기에서 얻을 오류는 이것이다 :

: "인수 1 'Extensions.Abstractions.Interfaces.IModelConverter'에서 변환 할 수 없습니다 'Extensions.Abstractions.Interfaces.IModelConverter'에"

그리고 추가 할 클래스는 이것이다 :

public class LanguageConverter : DocumentConverterCreatorBase<LanguageCollection> 
{ 
protected override void ActivateDocument(LanguageCollection collection, ServiceContext services, bool overrideIfNeeded) 
{ 
    ILocalizationService fs = services.LocalizationService; 
    foreach (LanguageType language in collection.List) 
    { 
    if (fs.GetLanguageByIsoCode(language.CultureAlias) != null && overrideIfNeeded) 
     fs.Delete(fs.GetLanguageByIsoCode(language.CultureAlias)); 

    if (fs.GetLanguageByIsoCode(language.CultureAlias) == null) 
     fs.Save(language.Construct(services)); 
    } 
} 

public override bool ContainsFile(LanguageCollection document, ServiceContext services) 
{ 
    ILocalizationService ls = services.LocalizationService; 
    foreach (LanguageType item in document.List) 
    { 
    if (ls.GetLanguageByIsoCode(item.CultureAlias) == null) 
     return false; 
    } 
    return true; 
} 

}

그리고 추상 클래스는 이것이다 :

public abstract class DocumentConverterCreatorBase<T>: IAssetConverter, IModelConverter<T>, IModelCreator where T : IDataCollection 

추상 클래스에는 인터페이스의 메소드에 대한 두 가지 추상 메소드가 있습니다.

IDataCollection은 데이터 목록 일뿐입니다. 인터페이스는 다음과 같습니다 :

public interface IDataCollection 
    { 
    int GetCount(); 
    } 
+1

어떤 오류가 있으며 어떻게 전송합니까? 코드를 넣을 수 있습니까? –

+1

** 우리가 볼 수있는 유일한 오류 **가 당신이 받고있는 오류가되도록 ** 복사, 붙여 넣기 및 코드를 컴파일 할 수있는 충분한 코드를 제공해 주시겠습니까? 지금 나는 많은 오류가 발생합니다. – Enigmativity

+0

글쎄, 내가 그것을 전혀 만들지 못하게하는 것은 오류가 아니다. 내가 얻은 것은 다음과 같습니다. "인수 1 : 'Extensions.Abstractions.Interfaces.IModelConverter '을 'Extensions.Abstrations.Interfaces.IModelCOnverter '"으로 변환 할 수 없습니다. " – patrick

답변

2

표시되는 문제점은 공분산입니다.

이러한 형식 정의가있는 경우 :

public class ModelConverterList : List<IModelConverter<IDataCollection>> { } 
public interface IModelConverter<in T> : IConverter where T : IDataCollection { } 
public interface IDataCollection { } 
public interface IConverter { } 

... 다음이 코드 :

private static ModelConverterList modelConverters = new ModelConverterList(); 

public static void AddModelConverter<T>(IModelConverter<T> converter) where T : IDataCollection 
{ 
    modelConverters.Add(converter); 
} 

... 다음과 같은 오류 얻을 : 심지어

CS1503 Argument 1: cannot convert from 'IModelConverter<T>' to 'IModelConverter<UserQuery.IDataCollection>'

TIDataCollection에서 상속 받았다는 것을 알고 있지만과 같은 것은 아닙니다.은 IModelConverter<IDataCollection>에서 상속됩니다. 그렇지 않습니다. 따라서 IModelConverter<T>에서 IModelConverter<IDataCollection>까지 캐스트가 없습니다.

public class ModelConverterList : List<IModelConverter<IDataCollection>> { } 
public interface IModelConverter<out T> : IConverter where T : class, IDataCollection { } 
public interface IDataCollection { } 
public interface IConverter { } 

private static ModelConverterList modelConverters = new ModelConverterList(); 

public static void AddModelConverter<T>(IModelConverter<T> converter) where T : class, IDataCollection 
{ 
    modelConverters.Add(converter); 
} 

하지만 out Tin T에서 IModelConverter의 정의를 변경하고 class 제약 조건을 추가했습니다 :

이 컴파일합니다.

+0

훌륭한 솔루션입니다. 하지만 인터페이스에서 가지고있는 메소드 때문에 T를 사용할 수 없습니다. 코드에서 뭔가 바뀌겠습니까? – patrick

+0

@patrick - 예, 샘플 코드를 컴파일 할 수 있지만 인터페이스가 손상 될 수 있습니다. 기본적으로 원하는 것을 할 수는 없습니다. – Enigmativity

+0

아, 그렇다면 T 또는 다른 솔루션이 포함 된 솔루션을 찾을 수 있는지 확인합니다. 그래도 도움을 주셔서 감사합니다. – patrick