[英]Using generics from non-generic class
我對泛型有疑問。 我寫了一個通用類。 我從該課程中派生其他課程。
最后,我想在另一個類中使用此派生類,但是我沒有找到有效的解決方案來使它正常工作。
這是我的簡化示例:
// Generic base class
public class Information<T>
{
public T StatusCode;
public bool Changed;
}
public class Status1 : Information<Status1.Codes>
{
public enum Codes { None = 0, }
public string AdditionalStatusInformation;
public Status1()
{
StatusCode = Codes.None;
}
}
public class Status2 : Information<Status2.Codes>
{
public enum Codes { OK = 0, }
public Status2()
{
StatusCode = Codes.OK;
}
}
到目前為止一切都很好。 我正在使用Json發送和讀取此信息,並且該方法適用於接收器和發送器。 與Status1和Status2類一起正常工作。
最后,我有一個通用的ErrorReporter類,我想在其中使用Status1或Status2類。 似乎這是不可能的。
public class ErrorReporter<T> where T : Information<T>
{
public readonly T Info = Activator.CreateInstance<T>();
public void Update()
{
if (Info.Changed)
{
Console.WriteLine(Info.StatusCode.ToString());
Console.WriteLine(JsonConvert.SerializeObject(Info));
}
}
}
似乎沒有辦法正確實例化此類。
我嘗試了這些
new ErrorReporter<Status1>()
new ErrorReporter<Status1.Codes>()
new ErrorReporter<Information<Status1.Codes>()
我正進入(狀態
The type 'TestApp.Program.Status1' cannot be used as type parameter 'T' in
the generic type or method 'TestApp.Program.ErrorReporter<T>'.
There is no implicit reference conversion from 'TestApp.Program.Status1' to
'TestApp.Program.Information<TestApp.Program.Status1>'.
或類似的錯誤消息。
我可能應該將ErrorReporter類移到Information類。
但是,從ErrorReporter類實例化新對象的正確方法是什么? 可能嗎?
您需要T
從Information<T>
派生,這不是您想要的。
我想您需要這個,在這里您需要為泛型提供type參數:
public class ErrorReporter<T, S> where T : Information<S>
{ }
只需多花一點錢,您就可以刪除反射調用:
public class ErrorReporter<T, S> where T : Information<S>, new()
{
public readonly T Info = new T();
}
問題是您正試圖將T
用於兩個目的:
StatusCode
就可以了) Information<T>
的類型參數) 現在,您可以只使ErrorReporter
泛型為兩個類型參數:
public class ErrorReporter<TSource, TCode> where TSource : Information<TCode>
{
public readonly TSource Info = Activator.CreateInstance<TSource>();
public void Update()
{
if (Info.Changed)
{
Console.WriteLine(Info.StatusCode.ToString());
Console.WriteLine(JsonConvert.SerializeObject(Info));
}
}
}
然后,您可以使用:
new ErrorReporter<Status1, Status1.Codes>()
或者您可以使它僅在代碼類型中通用,但避免通過反射構造源:
public class ErrorReporter<T>
{
// You could expose this as a property if you want. I would
// advise against exposing it as a field
private readonly Information<T> source;
public ErrorReporter(Information<T> source)
{
this.source = source;
}
public void Update()
{
if (Info.Changed)
{
Console.WriteLine(source.StatusCode.ToString());
Console.WriteLine(JsonConvert.SerializeObject(source));
}
}
}
並將其構造為:
var reporter = new ErrorReporter<Status1.Codes>(new Status1());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.