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.
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.[/quote]
Ah ok, obrigado pelas respostas.
Mas então vc teria uma ‘solução alternativa’ para este problema?
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.
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
{
}
[quote=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.[/quote]
Vlw Vini, esse ‘where T: class’ resolveu parte dos meus problemas, mas surgiram outros. Vou colocar o código aqui para poderem me ajudar…
public interface Formatter<T> where T: class
{
String format(T t);
T parse(String s);
}
public class DateFormatter: Formatter<DateTime>
{...}
mas ele acusa o seguinte 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>’
[quote=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).[/quote]
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>’
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.
[quote=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.[/quote]
Esse é o problema, tirando o 'where T: class", quando faço o seguinte:
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#…
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?
[quote=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?
[/quote]
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…