Embora a implementação de generics dele traga outras vantagens (como vc poder chamar new T, testar se o objeto é instanceof T ou saber o tipo de T por reflection), essa vantagem ele não tem.
J
j0nny
ViniGodoy:
Ah sim, seu problema envolve listas.
Nesse caso, realmente não é possível fazer algo similar aos wildcards em C#:
Embora a implementação de generics dele traga outras vantagens (como vc poder chamar new T, testar se o objeto é instanceof T ou saber o tipo de T por reflection), essa vantagem ele não tem.
Ah ok, obrigado pelas respostas.
Mas então vc teria uma ‘solução alternativa’ para este problema?
E para os generics serem nullable, tem como?
J
j0nny
windsofhell:
Eh algo assim que vc ta querendo fazer ?
Tirei o exemplo da documentacao.
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
public static void TestSwap()
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
System.Console.WriteLine(a + " " + b);
}
sobre passar null nos parametros. Da uma olhada nisso:
//Daniel
Vlw pela resposta, mas não é bem isso não cara…
E sobre o link, já li esse, mas não consegui usá-lo aqui, acho que não resolve o problema…
V
ViniGodoy
Os generics só são nullables se eles forem exclusivamente para classes. É que no C# tipos primitivos podem assumir generics.
Se você quiser manter a possibilidade de tipos primitivos, ao invés de null, você usa default:
Isso vai ser null para tipos de referência, 0 para tipos numéricos, false para booleans.
Se você realmente quiser restringir a tipos de referência, coloque uma claúsula where:
public class MinhaClasse<T> where : class {
}
O class ali no final indica que o tipo é de referência: pode ser classe ou interface. Como agora o C# sabe que se trata de um tipo assim, variáveis de um tipo T poderão receber null.
V
ViniGodoy
Para listas, eu tenho trabalhado com extension methods. Mas nunca precisei do wildcard “super”.
Para coisas mais simples, dá para usar a sintaxe do windsofshell. Ela criará um método diferente para cada tipo de lista:
public void metodo<V>(MinhaClasse<V> clazzObj) where V : class
{
}
Talvez até funcione isso aqui no lugar do super, mas nunca testei:
public void metodo<T, Z>(MinhaClasse<V> clazzObj, Comparator<Z> comparador) where V : class, Z : V
{
}
J
j0nny
ViniGodoy:
Os generics só são nullables se eles forem exclusivamente para classes. É que no C# tipos primitivos podem assumir generics.
Se você quiser manter a possibilidade de tipos primitivos, ao invés de null, você usa default:
Isso vai ser null para tipos de referência, 0 para tipos numéricos, false para booleans.
Se você realmente quiser restringir a tipos de referência, coloque uma claúsula where:
public class MinhaClasse<T> where : class {
}
O class ali no final indica que o tipo é de referência: pode ser classe ou interface. Como agora o C# sabe que se trata de um tipo assim, variáveis de um tipo T poderão receber null.
Vlw Vini, esse ‘where T: class’ resolveu parte dos meus problemas, mas surgiram outros. Vou colocar o código aqui para poderem me ajudar…
Error 2 The type ‘System.DateTime’ must be a reference type in order to use it as parameter ‘T’ in the generic type or method ‘Model.Formatter.Formatter<T>’
V
ViniGodoy
DateTime para o C# é um tipo primitivo.
Se você precisa usar com DateTime, use o default(T) e tire o where T : class
Aliás, faz até mais sentido, já que nada te impede de criar um formatador para floats e ints.
Outra opção é usar um wrapper, como DateTime?
(A ? é parte no nome do tipo).
J
j0nny
ViniGodoy:
DateTime para o C# é um tipo primitivo.
Se você precisa usar com DateTime, use o default(T) e tire o where T : class
Aliás, faz até mais sentido, já que nada te impede de criar um formatador para floats e ints.
Outra opção é usar um wrapper, como DateTime?
(A ? é parte no nome do tipo).
Não consegui entender esse default, não seria só para atribuição de valores?
E usando o wrapper DateTime?, ele aponta o erro…
Error 2 The type ‘System.DateTime?’ must be a reference type in order to use it as parameter ‘T’ in the generic type or method ‘Model.Formatter.Formatter<T>’
V
ViniGodoy
Onde você quer passar o null?
J
j0nny
Em um método que recebe o ‘T’…
View o erro que postei?
Parece que o DateTime? não e unm wrapper…
V
ViniGodoy
Pois é, aparentemente no C# os wrappers não são considerados reference types. Curioso, não sabia dessa…
Em todo caso, você só precisa do where T : class se for restringir seu formatador a tipos de referência. Como você vai usar com DateTime, não parece ser o caso.
Simplesmente retire esse where, instancia o fomatador para DateTime? e você poderá passar null no método.
J
j0nny
ViniGodoy:
Pois é, aparentemente no C# os wrappers não são considerados reference types. Curioso, não sabia dessa…
Em todo caso, você só precisa do where T : class se for restringir seu formatador a tipos de referência. Como você vai usar com DateTime, não parece ser o caso.
Simplesmente retire esse where, instancia o fomatador para DateTime? e você poderá passar null no método.
Esse é o problema, tirando o 'where T: class", quando faço o seguinte:
protectedoverrideList<Formatter><T>> DefaultFormatters<T>(){
List<Formatter><T>> formatters = new List<Formatter><T>>();formatters.Add(newDateFormatter(DateFormatter.DATE));formatters.Add(newDateFormatter(DateFormatter.TIME));returnformatters;}
o seguinte erro é apresentado:
Error 9 The best overloaded method match for ‘System.Collections.Generic.List<Model.Formatter.Formatter><T>>.Add(Model.Formatter.Formatter<T>)’ has some invalid arguments
Desculpe a insistência, mas senti algumas facilidades do Java em relação ao C#…
V
ViniGodoy
Ué, mas seu método DefaultFormatters retorna formatos para um tipo T?
Isso não seria possível nem no Java, já que com wildcards o método add seria bloqueado.
Se o tipo T fosse int, por exemplo, como você poderia retornar dois formatters de Date?
J
j0nny
ViniGodoy:
Ué, mas seu método DefaultFormatters retorna formatos para um tipo T?
Isso não seria possível nem no Java, já que com wildcards o método add seria bloqueado.
Se o tipo T fosse int, por exemplo, como você poderia retornar dois formatters de Date?
Desculpe o erro, estava retornando formatters para Object, mas assim não vai funcionar, por isso queria uma solução alternativa, pois no Java posso usar o ‘?’…
PS: Não estou na empresa agora, vou fazer mais testes amanha…