1

次のコードでは、メソッドentities = doSpecialStuff(entities);のどこかで何かが「欠落」しているため、オンラインで問題がありますdoSpecialStuff()

Error
The type 'T' cannot be used as type parameter 'T' in the generic type or method
'myWorkClass<T>.doSpecialStuff<T>(IEnumerable<T> entities)'. There is no implicit reference conversion from 'T' to 'ISpezial'.)

コード

ここに私の慣性構造があります

public class Baseclass { }

public interface ISpezial 
{ 
    int mySpecial{get;set;} 
}

public class Class1 : Baseclass { }

public class Class2 : Baseclass, ISpezial
{
    public int mySpecial{ get;set;}
}

これが私のデータプロバイダーです

public class myRepository
{
    public static IEnumerable<TResult> Load<TResult>() where TResult : Baseclass, new()
    {
        List<TResult> myEnum = new List<TResult>();

        if (typeof(ISpezial).IsAssignableFrom(typeof(TResult)))
        {
            myEnum.Add((new Class2() { mySpecial = 0 }) as TResult);
            myEnum.Add((new Class2() { mySpecial = 1 }) as TResult);
            myEnum.Add((new Class2() { mySpecial = 2 }) as TResult);
        }
        else
        {
            myEnum.Add((new Class1() as TResult));
            myEnum.Add((new Class1() as TResult));
            myEnum.Add((new Class1() as TResult));
        }

        return myEnum;
    }
}

そこには、ボスのように物事を行い、エラーを提供するクラスがあります

public class myWorkClass<T> where T : Baseclass, new()
{
    public void doNormalStuff()
    {
        var entities = myRepository.Load<T>();
        if (typeof(ISpezial).IsAssignableFrom(typeof(T)))
        {
            entities = doSpecialStuff(entities);
        }
    }

    public IEnumerable<T> doSpecialStuff<T>(IEnumerable<T> entities) where T : ISpezial
    {
        var list = new List<T>();

        return list.Where(special => special.mySpecial==2);
    }
}

さらなる質問

どこにいるのを避けるにはどうすればよいnew()ですか?

また、戻り値を変更せずに追加部分myRepositoryを変更するにはどうすればよいですか?myEnum.Add(new Class1());myEnum.Add((new Class1() as TResult));IEnumerable<TResult>

4

1 に答える 1

2

T (Baseclass または Baseclass の子) 間には暗黙的な変換がないため、ISpezial が代入可能かどうかを確認するだけでは不十分です (これは非常に優れています)。パラメーターをキャストし、それをキャストします。ただし、実際には最高のクラス設計ではありません。

 entities = doSpecialStuff(entities.Cast<ISpezial>()).Cast<T>();

2 番目の質問: Class2() および Class1() コンストラクターを明示的に呼び出すため、C# のポリモーフィズム/ジェネリック型付けに実際に依存していないため、new() 制約が存在します (new T() を記述した場合、例えば)。コードをそのように保つ限り、制約を取り除くことができます。

3番目: dynamicsキーワードを利用し、動的タイプのリストを作成し、最後の瞬間にのみキャストできます:

List<dynamic> myEnum = new List<dynamic>();
//your code
myEnum.Add((new Class2() { mySpecial = 0 })); //it's ok to write like you want it now
//your code
return myEnum.Cast<TResult>();
于 2013-05-03T08:25:38.547 に答える