これは初心者の質問である可能性が高いですが、意外にもグーグルは答えを提供しませんでした。
このかなり人工的な方法があります
T HowToCast<T>(T t)
{
if (typeof(T) == typeof(string))
{
T newT1 = "some text";
T newT2 = (string)t;
}
return t;
}
C++のバックグラウンドから来て、これが機能することを期待していました。ただし、上記の両方の割り当てに対して、「型 'T'を文字列に暗黙的に変換できません」および「型 'T'を文字列に変換できません」でコンパイルできません。
私は概念的に何か間違っているか、間違った構文を持っています。これを整理するのを手伝ってください。
ありがとうございました!
if
ブロックの中にあるにもかかわらず、コンパイラはT
がstring
であることを知りません。
したがって、キャストは許可されません。 (DateTime
をstring
にキャストできないのと同じ理由で)
object
(任意のT
にキャストできる)にキャストし、そこからstring
にキャストする必要があります(object
はstring
にキャストできるため) 。
例えば:
T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;
両方の行に同じ問題があります
T newT1 = "some text";
T newT2 = (string)t;
コンパイラはTが文字列であることを知らないため、それを割り当てる方法を知る方法がありません。しかし、チェックしたので、それを強制することができます
T newT1 = "some text" as T;
T newT2 = t;
tは既に文字列であるため、キャストする必要はありません。また、制約を追加する必要もあります。
where T : class
明示的な型をチェックしている場合、それらの変数を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;
}
クラスとメソッドの両方の汎用宣言がある場合にも、このエラーが発生します。たとえば、次のコードはこのコンパイルエラーを示します。
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();
}
}