Why is a type parameter required for a static method for a typical type?

public class BinarySearchTree<T> where T : IComparable<T> { public static BinarySearchTree<char> InitializeSampleCharacterBST() { var bst = new BinarySearchTree<char>(); bst.Insert('F'); bst.Insert('B'); bst.Insert('A'); bst.Insert('D'); bst.Insert('C'); bst.Insert('G'); bst.Insert('I'); bst.Insert('H'); return bst; } class Program { static void Main(string[] args) { var bst = BinarySearchTree.InitializeSampleCharacterBST(); } } 

Why is it illegal? He expects me to provide a type parameter to a method call for a class that does not make sense. A generic class or method is not used for a type parameter in a static context.

He wants me to write this call:

 var bst = BinarySearchTree<foo>.InitializeSampleCharacterBST(); 

Where foo can be any type that I want, regardless of whether the call to the static method returns a specially typed shared object.

+4
source share
4 answers

the BinarySearchTree and BinarySeachTree<Foo> classes are completely separate; language allows general type overloading. Perhaps declare this method for a non-generic pedigree class:

 public static class BinarySearchTree { public static BinarySearchTree<char> InitializeSampleCharacterBST() {...} } public class BinarySearchTree<T> {...} // rest of the code 

Otherwise ... to use T ? But what if the static method spoke with static fields? Not to mention which T use, each T gets different static fields (i.e., SomeType<Foo> has separate fields for SomeType<Bar> ).

+5
source

As Mark said, it is sometimes useful to overload a type to have a non-generic class - and that would be the case.

Why is this necessary, suppose that the static method was actually implemented as:

 public static BinarySearchTree<char> InitializeSampleCharacterBST() { Console.WriteLine(typeof(T)); return null; } 

This would be a perfectly valid code - it would be in a generic type, so it should have access to the type parameter ... but you are trying to call the method without providing a type type parameter, so it couldn’t Work. In your case, you are not using T anywhere in the method, but it is a coincidence. This is a bit like an instance method that does not use this : you are not using an instance, but you still cannot call it as if it were a static method.

Besides having separate static classes, another design method that might be useful is to split your type into non-general and common elements. Thus, in cases where it may be inconvenient to work out the exact type that you have, you really don't need to know it to call some of the members. For example, a collection interface hierarchy may have:

 public interface ISomeCollection { int Count { get; } void Clear(); } public interface ISomeCollection<T> : ISomeCollection { void Add(T item); } 

I myself used this technique for my port of protocol buffers in C #, and it turned out to be very useful (if somewhat complicated).

+5
source

You forget that type parameters not only appear in the type of the parameter / return method. They can also be displayed in the implementation:

 public static BinarySearchTree<char> InitializeSampleCharacterBST() { var forSomeReason = new T(); 

By placing your method inside a static class with a type parameter, you say that the method implementation (now or in some future revision) may depend on this type parameter.

If this is not the case, you will put the method in the wrong place.

+3
source

Since the type itself is Generic, you must specify a type argument, even if the static method of interest to you does not use an argument of that type. Its just the nature of generics in C # ... they don't exist in non-core form at any time. If they do, it will cause conflicts with a non-generic version of the same type.

0
source

Source: https://habr.com/ru/post/1286270/


All Articles