Ik heb een generieke methode met deze (dummy) code (ja ik weet dat IList predikaten heeft, maar mijn code gebruikt geen IList maar een andere verzameling, dit is in ieder geval niet relevant voor de vraag…)
static T FindThing<T>(IList collection, int id) where T : IThing, new()
{
foreach T thing in collecion
{
if (thing.Id == id)
return thing;
}
return null; // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead.
}
Dit geeft me een bouwfout
“Kan null niet converteren naar typeparameter
‘T’ omdat het een waardetype kan zijn.
Overweeg om in plaats daarvan ‘default(T)’ te gebruiken.”
Kan ik deze fout vermijden?
Antwoord 1, autoriteit 100%
Twee opties:
- Retourneer
default(T)
, wat betekent dat unull
retourneert als T een referentietype is (of een waarde met een null-waarde),0
voorint
,'\0'
voorchar
, enz. (Tabel met standaardwaarden (C#-referentie)) - Beperk T om een referentietype te zijn met de
where T : class
beperking en retourneer vervolgensnull
zoals normaal
Antwoord 2, autoriteit 10%
return default(T);
Antwoord 3, autoriteit 4%
U kunt uw beperkingen gewoon aanpassen:
where T : class
Dan is het retourneren van null toegestaan.
Antwoord 4
Voeg de klassebeperking toe als de eerste beperking aan uw generieke type.
static T FindThing<T>(IList collection, int id) where T : class, IThing, new()
Antwoord 5
-
Als je een object hebt, moet je typen
return (T)(object)(employee);
-
als u null moet retourneren.
return default(T);
Antwoord 6
Hieronder staan de twee opties die u kunt gebruiken
return default(T);
of
where T : class, IThing
return null;
Antwoord 7
Uw andere optie zou zijn om dit toe te voegen aan het einde van uw aangifte:
where T : class
where T: IList
Op die manier kun je null retourneren.
Antwoord 8
oplossing van TheSoftwareJedi werkt,
je kunt het ook archiveren met een paar waarde- en nullable-typen:
static T? FindThing<T>(IList collection, int id) where T : struct, IThing
{
foreach T thing in collecion
{
if (thing.Id == id)
return thing;
}
return null;
}
Antwoord 9
Voor de volledigheid is het goed om te weten dat u dit ook kunt doen:
return default;
Het geeft hetzelfde terug als return default(T);
Antwoord 10
Neem de aanbeveling van de fout… en gebruiker default(T)
of new T
.
Je moet een vergelijking in je code toevoegen om er zeker van te zijn dat het een geldige overeenkomst was als je die route volgt.
Overweeg anders mogelijk een uitvoerparameter voor “overeenkomst gevonden”.
Antwoord 11
Hier is een werkend voorbeeld voor Nullable Enum-retourwaarden:
public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct
{
return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value);
}
Antwoord 12
Vanwege IThing is de interface niet mogelijk om null te gebruiken. U moet dus standaard(T) gebruiken om de standaardwaarde voor het werkelijke type T te bepalen, dat is gedefinieerd voordat de functie wordt aangeroepen.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
IThing x = new List<Thing>().FindThing(1);
}
}
public static class Ext {
public static T FindThing<T>(this IList<T> collection, int id) where T : IThing, new()
{
foreach (T thing in collection)
{
if (thing.Id == id) return (T)thing;
}
//return null; //not work
//return (T)null; //not work
//return null as T; //not work
return default(T); //work
}
}
public interface IThing { int Id {get; set;} }
public class Thing : IThing { public int Id {get;set;}}
Antwoord 13
Nog een alternatief voor de twee hierboven gepresenteerde antwoorden. Als u uw retourtype wijzigt in object
, kunt u null
retourneren, terwijl u tegelijkertijd de niet-null-retour cast.
static object FindThing<T>(IList collection, int id)
{
foreach T thing in collecion
{
if (thing.Id == id)
return (T) thing;
}
return null; // allowed now
}