Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A .NET-keretrendszer 4 bemutatta a variancia támogatását számos meglévő általános interfészhez. A variancia-támogatás lehetővé teszi az ezen interfészeket megvalósító osztályok implicit átalakítását.
A .NET-keretrendszer 4-es verziójától kezdve a következő interfészek változatosak:
IEnumerable<T> (T kovariant)
IEnumerator<T> (T kovariant)
IQueryable<T> (T kovariant)
IGrouping<TKey,TElement> (
TKeyésTElementkovariant)IComparer<T> (T kontravariáns)
IEqualityComparer<T> (T kontravariáns)
IComparable<T> (T kontravariáns)
A .NET-keretrendszer 4.5-től kezdődően a következő interfészek variáns tulajdonságokat mutatnak:
IReadOnlyList<T> (T kovariant)
IReadOnlyCollection<T> (T kovariant)
A kovariancia lehetővé teszi, hogy egy metódus származtatottabb visszatérési típussal rendelkezzen, mint amelyet az interfész általános típusparamétere határoz meg. A kovariancia funkció szemléltetéséhez vegye figyelembe az alábbi általános felületeket: IEnumerable<Object> és IEnumerable<String>. A IEnumerable<String> felület nem örökli a IEnumerable<Object> felületet. A String típus azonban örökli a Object típust, és bizonyos esetekben érdemes lehet ezeknek a felületeknek az objektumait egymáshoz rendelni. Ez az alábbi példakódban látható.
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
A .NET-keretrendszer korábbi verzióiban ez a kód fordítási hibát okoz A C# és ha Option Strict be van kapcsolva, a Visual Basicben. De most használhatja a strings a objects helyett, mint az előző példában, mert a IEnumerable<T> felület kovariáns.
A kontravariancia lehetővé teszi, hogy egy metódus olyan argumentumtípusokat használjon, amelyek kevésbé származnak, mint az interfész generikus paramétere által megadottak. A contravariance szemléltetéséhez tegyük fel, hogy létrehozott egy osztályt BaseComparer az BaseClass osztály példányainak összehasonlításához. Az BaseComparer osztály megvalósítja az IEqualityComparer<BaseClass> felületet. Mivel a IEqualityComparer<T> felület jelenleg kontravariáns, a BaseComparer használható olyan osztályok példányainak összehasonlítására, amelyek a BaseClass osztályt öröklik. Ez az alábbi példakódban látható.
// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }
// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass>
{
public int GetHashCode(BaseClass baseInstance)
{
return baseInstance.GetHashCode();
}
public bool Equals(BaseClass x, BaseClass y)
{
return x == y;
}
}
class Program
{
static void Test()
{
IEqualityComparer<BaseClass> baseComparer = new BaseComparer();
// Implicit conversion of IEqualityComparer<BaseClass> to
// IEqualityComparer<DerivedClass>.
IEqualityComparer<DerivedClass> childComparer = baseComparer;
}
}
További példákért lásd: Variancia használata általános gyűjteményekhez készült felületekben (C#).
Az általános felületek varianciája csak referenciatípusok esetén támogatott. Az értéktípusok nem támogatják a varianciát. Például, IEnumerable<int> nem konvertálható implicit módon IEnumerable<object>-re, mert az egész számokat értéktípus képviseli.
IEnumerable<int> integers = new List<int>();
// The following statement generates a compiler error,
// because int is a value type.
// IEnumerable<Object> objects = integers;
Azt is fontos megjegyezni, hogy a variáns interfészeket megvalósító osztályok még mindig invariánsak. Például, bár List<T> implementálja a kovariant felületet IEnumerable<T>, nem konvertálható List<String>List<Object>implicit módon. Ezt az alábbi példakód szemlélteti.
// The following line generates a compiler error
// because classes are invariant.
// List<Object> list = new List<String>();
// You can use the interface object instead.
IEnumerable<Object> listObjects = new List<String>();