2010-04-16 16 views
7

Próbuję wykonać następujące czynności:Dlaczego nie mogę wymusić klas pochodnych na konstruktorach bez parametrów?

class Program 
{ 
    static void Main(string[] args) 
    { 
     foo<baz> fooObject = new foo<baz>(); 
     AnotherClass<baz> _baz = new AnotherClass<baz>(); 
     _baz.testMethod(fooObject); 
    } 
} 

public class AnotherClass<T> where T : bar 
{ 
    public void testMethod(foo<T> dummy) 
    { 
     foobar = dummy; 
    } 

    private foo<T> foobar = null; 
} 

public class foo<T> where T : bar, new() 
{ 
    public foo() 
    { 
     _t = new T(); 
    } 

    private T _t; 

} 

public abstract class bar 
{ 
    public abstract void someMethod(); 
    // Some implementation 
} 

public class baz : bar 
{ 
    public override void someMethod() 
    { 
     //Implementation 
    } 
}  

I pojawia się błąd wyjaśniając, że „T” musi być non-abstrakcyjny typ z konstruktora bez parametrów publicznej w celu wykorzystania go jako parametru „T” rodzaj ogólny lub metoda. W pełni rozumiem, dlaczego tak się dzieje, a także rozumiem, że mogłem przekazać wstępnie zainicjowany obiekt typu "T" jako argument konstruktora, aby uniknąć konieczności "nowego" go, ale czy jest jakiś sposób obejścia tego? w jaki sposób wymusić klas, które pochodzą z "bar" do dostarczania konstruktorów bez parametrów?

Naprawiono - Brakowało mi "nowego()" ograniczenia w programie AnotherClass().

Odpowiedz

5

Czy nie brakuje new() ograniczenie na swoim AnotherClass?

public class AnotherClass<T> where T : bar, new() 

Bez tego VS2010 odmawia kompilacji, z tym, że działa dobrze.

+0

Dzięki, to chyba naprawiło! –

0

Czy nie jest to ogólna składnia new(), a nie tylko nowa?

Również robisz ten kod w środku klasy, a nie w zależności, która z pewnością go przegroda:

_t = new T(); 

Edit:

Ok, więc po Czyszczenie składni, domyślam się, że problem polega na tym, że 'baz' nie ma konstruktora bez parametrów. Nie znam żadnego sposobu, w jaki można to wymusić.

Istnieje podobne pytanie here, które może pomóc trochę.

+0

"W środku klasy": jest to tylko deklaracja pola z wartością początkową. –

+0

Naprawiono, dzięki. Mój zły nawyk na pół-pseudokod, w połowie prawdziwy kod! –

7

Poprawna składnia jest

public class foo<T> where T : bar, new() 
+0

Przepraszam, napisałem to w pośpiechu. –

0

Jak obejść - Możesz przekazać delegatowi tworząc instancję typu trzeba:

Func<T> creator = ... 

    _t = creator(); 
1

Kod kompiluje w VS2010.

Prawdopodobnie chcesz zamiast wykorzystywać interfejsy:

public class foo<T> where T : ibar, new() 
... 

public interface ibar 
{ 
    void someMethod(); 
} 

public abstract class bar : ibar 
{ 
    public abstract void someMethod(); 
    // Some implementation 
} 
+0

To generuje ten sam problem dla mnie ... –

0

najpierw usunąć "new()" z hasła "gdzie" klasy "Foo" Po muszą zmieniać konstruktora jako

public foo() 
{ 
    _t = Activator.CreateInstance<T>(); 
} 

Dla mnie działa!

Powiązane problemy