mam funkcje publiczne tak:kompilator nie wywołanie odpowiedniego przeciążenie rodzajowe kiedy zapadają typu wartości
public static T Get<T>(this Mango m, T defaultValue = default(T)) where T : class
{
//do something; return something;
}
public static T? Get<T>(this Mango m, T? defaultValue = default(T?)) where T : struct
{
//do something; return something;
}
Zasadniczo chcę indywidualnie obsługiwać typy referencyjne oraz zerowalne typów. Kompiluje; dopóki nie wezwę typów wartości. Dla typów odniesienia kompiluje.
mango.Get<string>(); // compiles..
mango.Get(""); // compiles..
mango.Get<int>(); // The type 'int' must be a reference type in order to use it as
// parameter 'T' in the generic type or method Get<T>(Mango, T)
//also // The call is ambiguous between the following methods or properties:
// Get<int>(Mango, int) and Get<int>(Mango, int?)
Co prawdziwy dwuznaczność jest tutaj? Kiedy T
jest int
, czy nie można nazwać przeciążeniem strukturalnym? również:
mango.Get<int>(0); // The type 'int' must be a reference type in order to use it as
// parameter 'T' in the generic type or method Get<T>(Mango, T)
Dlaczego kompilator tylko wykrywanie przeciążenia typu odniesienia? Próbowałem mieć dwa oddzielne przeciążenia:
public static T Get<T>(this Mango m) where T : class
{
return default(T);
}
public static T? Get<T>(this Mango m) where T : struct
{
return default(T);
}
public static T Get<T>(this Mango m, T def) where T : class
{
return default(T);
}
public static T? Get<T>(this Mango m, T? def) where T : struct
{
return default(T);
}
Problem nadal występował. I oczywiście, pierwsze dwie metody, których tutaj nie skompilowałem od czasu przeciążenia, nie działają jedynie na podstawie ograniczeń.
Próbowałem usuwając ograniczony przeciążać class
i utrzymanie tylko jednego struct
ograniczona, podobnie jak to:
public static T? Get<T>(this Mango m, T? defaultValue = default(T?)) where T : struct
{
//do something; return something;
}
mango.Get<int>(); // voila compiles!
mango.Get<int>(0); // no problem at all..
// but now I can't have mango.Get<string>() for instance :(
jestem tylko pozostaje zmiana nazwy dwie funkcje? Uważam, że właściwe jest posiadanie zunifikowanej nazwy, aby osoba dzwoniąca po prostu nie musiała się martwić o szczegóły implementacji, ale wystarczy zadzwonić pod numer Get
dla dowolnego typu.
Aktualizacja: Rozwiązanie Marca nie działa, jeśli muszę uniknąć opcjonalnego parametru.
mango.Get<int>(); // still wouldnt work!!
Ale to nie magia :(:(
public static bool IsIt<T>(this T? obj) where T : struct
{
return who knows;
}
public static bool IsIt<T>(this T obj) where T : class
{
return perhaps;
}
Wszelkimi sposobami Czekam ten sam błąd kompilatora (według mnie), żeby mnie zdenerwować. Ale nie działa tym razem .
Guid? g = null;
g.IsIt(); //just fine, and calls the struct constrained overload
"abcd".IsIt(); //just fine, and calls the class constrained overload
Więc jeśli rozdzielczość przeciążenie jest przed ograniczeniem sprawdzenie jak mówi Marc, nie powinien dostać ten sam błąd i tym razem? Ale nie. Dlaczego czy tak jest? Co się do cholery dzieje? : x
W połowie postu zamierzałem zasugerować, aby wypróbować tylko wersję struct, ale już to zrobiłeś i kompiluje. _Semems_ to dla mnie prawdziwy błąd i powinien zostać zgłoszony. –
@JohnWillemse: Brak błedu, zobacz odpowiedź Marks. –
@ Daniel Hilgarth nie może być błędem, ale z pewnością, gdyby był obsługiwany, to może być przydatna funkcja! – nawfal