-
Notifications
You must be signed in to change notification settings - Fork 1
Exercícios
Instalar o Visual Studio 2017 em INGLÊS
Escrever o código C# correspondente ao programa IL ex1.il
Considere a definição da classe Program em Common Intermediate Language (CIL). Indique e justifique (descrevendo o que faz cada um dos métodos), o output resultante da execução do programa. Para consultar o significado das operações IL siga este link.
Considere o código fonte em Sum.cs. Compile para .exe
.
- Usando o
ildasm
, grave o código intermédio deSum.exe
emSum.il
- Abra o
Sum.il
num editor de texto e analise o código intermédio. - No método
SumTwo
presente emSum.il
, duplique a instruçãoldarg.0
de maneira a que o argumento no índice 0 seja carregado duas vezes para o stack de avaliação. - Comente a linha com o código
.maxstack 2
- Recompile o assemly usando a ferramenta
ilasm.exe
ilasm Sum.il /EXE /OUTPUT=Sum2.exe
- Execute a nova aplicação
- Verifique a nova aplicação com o
peverify.exe
e analise o resultado
Escreva a classe Student
com os seguintes membros:
- propriedades get/set (o setter é privado):
string Name
,int Number
- Construtores:
Student()
,Student(int nr, string name)
Realize um programa de teste que cria objetos Student
e imprime a sua informação na consola. Realize um programa que faz introspeção (usando o namespace System.Reflection
) à classe Student
; deve obter o representante do tipo (typeof(Student
)) e de seguida apresentar na consola todos os membros públicos (propriedades e construtores) definidos no tipo Student
.
O método GetAssembly(Type t)
de Assembly
(Assembly.GetAssembly(Type t)) retorna um representante do componente (Assembly
) onde foi definido o tipo t
. Usando este método e ainda o GetTypes()
implemente a função utilitária List<Type> GetDerivedTypesOf(Type t)
que retorna uma lista com todos os tipos que estendam direta ou indiretamente de t
.
Considere a classe Student
presente em Exercicio7.cs. Implemente a classe ValidatorAttribute
(presente em ValidatorAttribute.cs) que corresponde ao atributo aplicado à propriedade Nr
. Além de escrever esta classe, complete também a classe NumberValidator
de acordo com a sugestão de implementação presente nos comentários da classe.
- class Sammy : Attribute { public int Nr { get; set; } }
- [Sammy(Nr = 71)] class Game { }
- [Sammy(Nr = App.Foo())] class Deal { }
- public class App {
- public static int Foo() { return 17; }
- static void Main() {
- typeof(Game).GetCustomAttribute().Nr = 19;
- Console.WriteLine(typeof(Game).GetCustomAttribute().Nr);
- }
- }
Para a definição dada de Sammy
, Game
, Deal
e App
:
a) __ a instrução da linha 3 dá erro de compilação.
b) __ a instrução da linha 8 retorna 71.
c) __ a instrução da linha 7 lança uma excepção.
d) __ a instrução (new Sammy()).Nr = 15;
dá erro de compilação.
interface IBean {
void Set(int v);
int Get();
}
struct S : IBean {
public int x;
public void Set(int v) { this.x = v; }
public int Get() { return this.x; }
}
Dadas as variáveis s
e i
definidas pelas expressões: S s = new S(); IBean i = s;
a) __ A execução de ((IBean) s).Set(11); Console.WriteLine(s.x);
tem o output 11.
b) __ A execução de ((S) i).Set(11); Console.WriteLine(i.Get());
tem o output 11.
c) __ A execução de s.x = 11; Console.WriteLine(i.Get());
tem o output 11.
d) __ A execução de s.Set(11); Console.WriteLine(i.Get());
tem o output 11.
Com as classes do espaço de nomes Reflection.Emit
...
(a) ____ é possível acrescentar métodos a classes já existentes.
(b) ____ é possível acrescentar novos tipos num assembly existente.
(c) ____ é possível gerar mais do que uma definição de um tipo no presente assembly dinâmico.
(d) ____ é possível usar um tipo gerado num assembly dinâmico mesmo que não se guarde a referência para a instância de Type
na altura da geração.
class R { public int i; }
struct V { public int i; }
... public static void Main() {
R r = new R();
R r2 = new R();
V v = new V();
V v2 = new V ();
Console.WriteLine(v.Equals(v));
Console.WriteLine(v.Equals(v2));
Console.WriteLine(object.ReferenceEquals(v, v));
Console.WriteLine(r.Equals(r));
Console.WriteLine(r.Equals(r2));
}
Relativamente ao código acima...
a) ___ ... são realizadas duas operações de box e o resultado é: true
, true
, true
, true
, false
.
b) ___ ... são realizadas cinco operações de box resultantes das chamadas a WriteLine(object)
.
c) ___ ... são realizadas quatro operações de box e o resultado é: true
, true
, false
, true
, false
.
d) ___ ... é possível eliminar algumas operações de box ocorridas em Main
sem alterar o código de Main
e sem alterar a categoria de R
e V
, mas fazendo outras alterações ao código apresentado.
class A {
public virtual void Foo() { }
}
class App {
void Main() {
A a = new A();
a.Foo();
}
}
Para a instrução a.Foo()
o compilador de C# gera: ldloc.0 callvirt instance void A::Foo()
Alterando a definição de Foo
para:
a) ___ public void Foo(){}
o compilador gera: ldloc.0 call instance void A::Foo()
b) ___ public void Foo(){}
o compilador gera: call instance void A::Foo()
c) ___ public static void Foo(){}
e a.Foo();
alterada para A.Foo();
o compilador gera: ldloc.0 call void A::Foo()
d) ___ public static void Foo(){}
e a.Foo();
alterada para A.Foo();
o compilador gera: call void A::Foo()
Escreva em IL o código do construtor e do método InvokeAll
da classe B
.
delegate object Func(int p);
abstract class A {
protected Func Handlers { get; set; }
protected int MaxNumHandlers { get; set; }
protected A(int maxNumHandlers) {
this.MaxNumHandlers = maxNumHandlers;
}
} class B : A
{
public B() : base(10) { Handlers = Bundle; }
private object Bundle(int p) { return p; }
public object InvokeAll(object parameter) {
return Handlers((int)parameter);
}
}
Acrescente à interface IEnumerable<T>
suporte para a operação lazy genérica Chunk
, que recebe uma sequência de T
e produz uma nova sequência de sequências de T
(i.e. IEnumerable<IEnumerable<T>>
) obtida separando a sequência fonte de acordo com o predicado passado a Chunk
(e.g. v => v % 2 == 0
). Ou seja, o último elemento de cada subsequência satisfaz o predicado, sendo que os anteriores elementos não. As sequências deverão ser lazy.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<IEnumerable> chunked = numbers.Chunk(v => v % 2 == 0);
foreach (IEnumerable s in chunked) {
Console.WriteLine(String.Join(",", s));
}
Output:
1,2
3,4
5,6
7,8
9,10