web-dev-qa-db-ja.com

タイプ 'T'の値は変換できません

これは初心者の質問である可能性が高いですが、意外にもグーグルは答えを提供しませんでした。

このかなり人工的な方法があります

T HowToCast<T>(T t)
{
    if (typeof(T) == typeof(string))
    {
        T newT1 = "some text";
        T newT2 = (string)t;
    }

    return t;
}

C++のバックグラウンドから来て、これが機能することを期待していました。ただし、上記の両方の割り当てに対して、「型 'T'を文字列に暗黙的に変換できません」および「型 'T'を文字列に変換できません」でコンパイルできません。

私は概念的に何か間違っているか、間違った構文を持っています。これを整理するのを手伝ってください。

ありがとうございました!

129
Alex

ifブロックの中にあるにもかかわらず、コンパイラはTstringであることを知りません。
したがって、キャストは許可されません。 (DateTimestringにキャストできないのと同じ理由で)

object(任意のTにキャストできる)にキャストし、そこからstringにキャストする必要があります(objectstringにキャストできるため) 。
例えば:

T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;
258
SLaks

両方の行に同じ問題があります

T newT1 = "some text";
T newT2 = (string)t;

コンパイラはTが文字列であることを知らないため、それを割り当てる方法を知る方法がありません。しかし、チェックしたので、それを強制することができます

T newT1 = "some text" as T;
T newT2 = t; 

tは既に文字列であるため、キャストする必要はありません。また、制約を追加する必要もあります。

where T : class
9
Doggett

明示的な型をチェックしている場合、それらの変数をTとして宣言するのはなぜですか?

T HowToCast<T>(T t)
{
    if (typeof(T) == typeof(string))
    {
        var newT1 = "some text";
        var newT2 = t;  //this builds but I'm not sure what it does under the hood.
        var newT3 = t.ToString();  //for sure the string you want.
    }

    return t;
}
1
Austin Salonen

クラスとメソッドの両方の汎用宣言がある場合にも、このエラーが発生します。たとえば、次のコードはこのコンパイルエラーを示します。

public class Foo <T> {

    T var;

    public <T> void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}

このコードはコンパイルされます(メソッド宣言からTが削除されていることに注意してください):

public class Foo <T> {

    T var;

    public void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}
0
John