2013-03-23 3 views
0

Так что я делал некоторые эксперименты, и я обнаружил, что в то время как это:Почему я могу наследовать от общего типа во время выполнения, но не компилировать время?

public class SelfOfT 
{ 
    // This won't compile 
    public class FailureOf<T> : T 
    { 

    } 
} 

выходит из строя, это, с другой стороны:

public class SelfOfT 
{ 
    public interface IMyInterface 
    { 

    } 

    public static void Second() 
    { 
     // This works fine, and achieves the same end as what I'm trying to do with FailureOf<T> 
     AssemblyName name = new AssemblyName("Dynamics"); 
     AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); 
     ModuleBuilder modbuilder = asmBuilder.DefineDynamicModule("MyModule"); 
     TypeBuilder typeBuild = modbuilder.DefineType("SuccessfulOf", TypeAttributes.Public); 

     typeBuild.AddInterfaceImplementation(typeof(IMyInterface)); 
     var TParam = typeBuild.DefineGenericParameters(new String[] { "T" }).First(); 
     TParam.SetGenericParameterAttributes(GenericParameterAttributes.None); 

     Type myType = typeBuild.CreateType(); 
     Type genericMyType = myType.MakeGenericType(typeof(IMyInterface)); 

     IMyInterface my = (IMyInterface)Activator.CreateInstance(genericMyType); 

    } 
} 

работает отлично. Похоже, что это сэкономит массу неприятностей, чтобы просто сделать это доступным во время компиляции, если я смогу сделать это во время выполнения в любом случае.

+1

Куда во втором фрагменте вы заявляете, что 'SuccessfulOf ' extends 'T'? – dtb

+0

На основании ответов я вижу, что, поскольку я знаю, что '' должно быть, я могу уйти от того, что делаю. Но я думаю, вопрос в том, почему я могу реализовать 'IEnumerable ', если я не могу сделать '' сам? В обеих ситуациях «T» неизвестно. – sircodesalot

+0

@sircodesalot, с ': IEnumerable ', вы просто передаете этот аргумент типа. Это совсем другая идея, чем подклассификация от произвольного типа, или реализация этого тоже, если на то пошло. Вот почему у вас не может быть класса C : object, T'. Было бы интересно, если бы язык допускал такую ​​выразительность, но C# этого не делает. –

ответ

3

Ваш код, который использует отражение фактически определяет это:

public class SuccessfulOf<T> : IMyInterface 
{ 

} 

Вы не можете делать то, что вы хотите (class FailureOf<T> : T), так как базовый тип T должен быть известен во время компиляции. Во время выполнения с отражением вы все равно не можете этого сделать, поскольку T должен быть известен.

4

Хм, вам также не разрешено делать это во время выполнения.

Обратите внимание, что в вашем случае вы находитесь не, указав класс для наследования.

Для этого вам необходимо использовать одну из перегрузок до DefineType, которая принимает параметр Type для наследования.

Однако, во время выполнения, вы не разрешено указывать T либо для этого параметра, вы должны указать тип конкретных, что не было бы никакой разницы от времени компиляции.

1

Потому что во втором коде вы объявляете тип public class FailureOf<T> : IMyInterface, а не public class FailureOf<T> : T.

Даже если вы объявляете общий тип в окружающем классе, вы все равно не можете наследовать его, потому что вы не можете наследовать параметр типа.

Смежные вопросы