Официальный учебник может вам пригодиться.
│ Class │ Package │ Subclass │ Subclass │ World │ │ │(same pkg)│(diff pkg)│ ────────────┼───────┼─────────┼──────────┼──────────┼──────── public │ + │ + │ + │ + │ + ────────────┼───────┼─────────┼──────────┼──────────┼──────── protected │ + │ + │ + │ + │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── no modifier │ + │ + │ + │ │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── private │ + │ │ │ │ + : accessible blank : not accessible
это невозможно, насколько мне известно.
строка:
List<ValuePair> list = new List<ValuePair>();
, которую вы написали в своем примере, не предоставляет конкретный тип для T, и это проблема , как только вы его передадите, вы можете добавить объект только этого типа.
В общем случае вам придется либо использовать List<object>
, либо создать не общий базовый класс, например
public abstract class ValuePair
{
public string Name { get; set;}
public abstract object RawValue { get; }
}
public class ValuePair<T> : ValuePair
{
public T Value { get; set; }
public object RawValue { get { return Value; } }
}
. Тогда вы можете иметь List<ValuePair>
.
Теперь существует одно исключение: ковариантные / контравариантные типы в C # 4. Например, вы можете написать:
var streamSequenceList = new List<IEnumerable<Stream>>();
IEnumerable<MemoryStream> memoryStreams = null; // For simplicity
IEnumerable<NetworkStream> networkStreams = null; // For simplicity
IEnumerable<Stream> streams = null; // For simplicity
streamSequenceList.Add(memoryStreams);
streamSequenceList.Add(networkStreams);
streamSequenceList.Add(streams);
Это неприменимо в ваш случай, потому что:
T
происходит «in» и «out» API IEnumerable<int>
не является IEnumerable<object>
) Нет, это невозможно. Вы можете создать в вашем случае базовый класс ValuePair
, из которого выводится ValuePair<T>
. Зависит от ваших целей.
Нет, если у вас нет универсального базового типа ValuePair
с ValuePair<T> : ValuePair
(он также будет работать для интерфейса) или используйте List<object>
. На самом деле это работает разумно:
public abstract class ValuePair
{
public string Name { get; set; }
public object Value
{
get { return GetValue(); }
set { SetValue(value); }
}
protected abstract object GetValue();
protected abstract void SetValue(object value);
}
public class ValuePair<T> : ValuePair
{
protected override object GetValue() { return Value; }
protected override void SetValue(object value) { Value = (T)value; }
public new T Value { get; set; }
}