1

In the following example, the comment is meant to check if a type is instantiable or usable:

class TypeContract
{
    Type indicator;

    public TypeContract(Type type)
    {
        // if (!type.IsInstantiable)
        // {
        //    throw new ArgumentException();
        // }

        indicator = type;
    }
}

For reference, System.String is instantiable, but System.Convert, IDictionary<,> and TKey are not. Note that constructor accessibility is not a concern in terms of classes.

How does the C# compiler check this? Is there a reliable type attribute? Perhabs it uses a manual check like:

!((type.IsAbstract && type.IsSealed) || type.IsGenericParameter || type.ContainsGenericParameters)

Avenicci
  • 121
  • 5
  • 1
    "For reference, `System.String` is instantiable, but `System.Convert`, `IDictionary<,>` and `TKey` are not." What *exactly* do you mean by this? What criteria are you trying to impose? – Jon Skeet Dec 15 '15 at 15:05
  • By "Is Instantiantiable" do you mean Value vs Reference type? Or do you mean "has a public constructor I can use?" Or maybe even both? – mclark1129 Dec 15 '15 at 15:07
  • I stuggle to find known terminology, what I practically mean is: What types can be referred to in code, without `typeof` . – Avenicci Dec 15 '15 at 15:08
  • 3
    Note that your mention of `TKey` is incorrect. Since you're checking the metadata via `Type` at runtime, `TKey` may be instantiable depending on the `Type` passed in for it. – David Dec 15 '15 at 15:09
  • @Avavol - `TKey` is descriptive, so certainly not usable. – Avenicci Dec 15 '15 at 15:10
  • 2
    What about classes that have private constructors that are exposed via public static methods? – DavidG Dec 15 '15 at 15:10
  • 1
    Actually you may access EVERY type (includinbg interfaces which are not instantiable) via `typeof`. – MakePeaceGreatAgain Dec 15 '15 at 15:14
  • Seems to me you're mixing things up here. `IDictionary` is an interface; you can't create an instance of an interface, though you can instantiate a type that implements the interface. `System.Convert` is a static class; you can't create an instance of a static class. TKey is typically the type parameter for a generic class or method; it's like the argument to a function. The rules for each would be different. – Tony Vitabile Dec 15 '15 at 15:14
  • @DavidG - Constructor accessibility is not a concern. – Avenicci Dec 15 '15 at 15:14
  • The compiler does not need to check for those weird attributes, it simply checks if the class is actually an interface or abstract or even static, that´s it. – MakePeaceGreatAgain Dec 15 '15 at 15:16
  • This doesn't make any sense really. You can create a class with only private constructors which renders it "uninstantiatable". – DavidG Dec 15 '15 at 15:16
  • @DavidG - Thats fine because I'm not interested in implementation details, I need to know whether a type is instantiable (at all) and referable as an object or structure, even if that involves an interface. I know that `Type` has plenty of properties which lend a good start, but I need a clean approach. – Avenicci Dec 15 '15 at 15:21

2 Answers2

4

Type.GetConstructors returns the public constructors of a class.

You can check if it returns an empty list

Matteo Umili
  • 3,412
  • 1
  • 19
  • 31
2

Get the Type object for the class and check the following attributes:

Class is static: type.IsAbstract && type.IsSealed (see this question)

Class is an interface: type.IsInterface

Class is an enum: type.IsEnum

Class is a generic parameter: type.IsGenericParameter

Check the documentation for the Type class here for more info on the properties it provides.

After that, you can check the available constructors.

Community
  • 1
  • 1
Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123