[英]Safely cast a Generic type in C#
如何根據給定的泛型類型安全地強制轉換並返回m_obj。
private IObject m_obj;
public bool TryGetAs<T>(out T value) where T :IObject
{
value = m_obj as T; // The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint
// value = (T)m_obj; This compiles!
if (value != null)
return true;
return false;
}
我知道,如果相反,如果m_obj我有一個列表,我可以簡單地做到這一點:
private readonly IList<Object> m_objects;
internal IList<T> Collect<T>() where T : IObject
{
return m_objects.OfType<T>().ToList();
}
但是我找不到以前的代碼的解決方案。
public interface IObject
{
}
我的答案:
public bool TryGetAs<T>(out T value) where T :IObject
{
value = default(T);
if (!(m_obj is T))
return false;
value = (T)m_obj;
return true;
}
as
運算符保留用於引用類型。 如果T
始終是引用類型,則解決方案是向TryGetAs<T>
添加class
約束。 如果T
也可以是值類型,則這不是選項。 在這種情況下,可以使用is
運算符:
public bool TryGetAs<T>(out T value) where T : IObject
{
if(m_obj is T)
{
value = (T)m_obj;
return true;
}
else
{
value = default(T);
return false;
}
}
在C#7.0,你可以把它簡化像這樣(和提高性能,因為你並不需要的is
投再另一種類型的施法):
public bool TryGetAs<T>(out T value) where T : IObject
{
if(m_obj is T tValue)
{
value = tValue;
return true;
}
else
{
value = default(T);
return false;
}
}
public bool TryGetAs<T>(out T value) where T : class, IObject
{
value = m_obj as T;
return (value != null);
}
將與最終解決方案一樣,並且可能更快(因為空檢查比is
檢查更快)。
如果所有IObject
實現都是引用類型( class
)而不是值類型( struct
), 則不包括class
修飾符沒有任何好處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.