“Where T: class, new ()” ne anlama geliyor?


Yanıtlar:


329

Bu, genel parametrede bir kısıtlamadır T. Bir olmalıclass (başvuru türü) olmalı ve genel bir parametresiz varsayılan yapıcıya sahip olmalıdır.

Araçlarının Tbir olamaz int, float, double, DateTimeya da herhangi bir başka struct(değer türü).

stringVarsayılan veya parametresiz bir kurucuya sahip olduğu sürece a veya başka bir özel referans türü olabilir.


5
Sadece açıklamak için, nerede T ... 'nin bir parçası olarak sınıf maddesine sahip değilseniz, int, float, double
vb.Kullanmak

1
@AboutDev doğruysa, genel tip parametrenize kısıtlamalar koymak zorunda değilsiniz. Ancak, yalnızca başvuru veya değer türleri üzerinde çalışmayı bekleyen bir genel oluşturuyorsanız, belirtmeniz gerekir. Kısıtlama olmadan, referans türlerini (sınıflar) veya değer türlerini (yapılar (int, float, double ...)) bekleyebilirsiniz.
NerdFury

1
Nerede T: [arabirim adı], yeni ()? Yine de parametresiz bir kurucuya ihtiyacınız var mı?
Vince Tino

3
Justin'in yorumunu açıklığa kavuşturmak için, boş bir kurucuda herhangi bir ifade yoktur (varsayılan kurucu gibi), parametresiz bir kurucu ise ifadeler içerebilir (bir listeyi başlatmak gibi).
DharmaTurtle

@VinceTino: new()"herkese açık parametresiz bir kurucuya sahip olmalı" ifadesini tam olarak belirtir
Flater

162

Bunlar genel tip kısıtlamalarıdır. Sizin durumunuzda bunlardan iki tane var:

where T : class

Türün Tbir başvuru türü (bir değer türü değil) olması gerektiği anlamına gelir .

where T : new()

Türün Tparametresiz bir kurucuya sahip olması gerektiği anlamına gelir . Bu kısıtlamaya sahip olmak T field = new T();, kodunuzda başka türlü yapamayacağınız gibi bir şey yapmanıza izin verecektir .

Daha sonra elde etmek için virgül kullanarak ikisini birleştirirsiniz:

where T : class, new()

İkinci ve üçüncü için iyi noktalar, sadece bilgi eklemek için, bence ikinci nokta jenerik tipte yansıma yaparken faydalıdır. Örneğin. Tt = yeni T (); t.GetType (). GetProperty ("ID"). SetValue (t, uniqueId, null);
Jerry Liang

1
Yapıların varsayılan kurucuları bulunamadığından, new () zaten sınıf anlamına geldiğinden T: sınıfının, new (), nerede olduğunu söylemek gereksizdir.
DharmaTurtle

@DharmaTurtle, "yapılar açık parametresiz kurucular içeremez" anlamına gelmez. kaynak: msdn.microsoft.com/tr-tr/library/aa288208(v=vs.71).aspx
rustem

121

burada T: yapı

Tür bağımsız değişkeni bir değer türü olmalıdır. Null değeri dışındaki herhangi bir değer türü belirtilebilir. Daha fazla bilgi için bkz. Null Edilebilir Türleri Kullanma (C # Programlama Kılavuzu).

burada T: sınıf

Tür bağımsız değişkeni, herhangi bir sınıf, arabirim, temsilci veya dizi türü dahil olmak üzere bir başvuru türü olmalıdır. (Aşağıdaki nota bakın.)

burada T: new () Tür bağımsız değişkeninde genel parametresiz bir kurucu bulunmalıdır. Diğer kısıtlamalarla birlikte kullanıldığında, yeni () kısıtlamanın en son belirtilmesi gerekir.

burada T: [temel sınıf adı]

Tür bağımsız değişkeni belirtilen temel sınıftan olmalı ya da bu sınıftan türetilmelidir.

burada T: [arayüz adı]

Tür bağımsız değişkeni belirtilen arabirim olmalı ya da uygulanmalıdır. Birden fazla arabirim kısıtlaması belirtilebilir. Kısıtlayıcı arayüz de genel olabilir.

burada T: U

T için sağlanan tür bağımsız değişkeni, U için sağlanan bağımsız değişken olmalıdır ya da bu türden türetilebilir. Buna çıplak tür kısıtlaması denir.


23
Bu yararlıydı, ancak kaynağa bağlantı .
Skean

26

class& , generic type parametresindekinew 2 kısıtlamadırT .
Sırasıyla şunları sağlarlar:

class

Tür bağımsız değişkeni bir başvuru türü olmalıdır; bu, herhangi bir sınıf, arabirim, temsilci veya dizi türü için de geçerlidir.

new

Type bağımsız değişkeninin genel parametresiz bir kurucusu olmalıdır. Diğer kısıtlamalarla birlikte kullanıldığında, yeni () kısıtlamanın en son belirtilmesi gerekir.

Kombinasyonları, türün Referans TürüT olması gerektiği anlamına gelir ( Değer Türü olamaz ) ve parametresiz bir kurucuya sahip .

Misal:

struct MyStruct { } // structs are value types

class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one

class MyClass2 // parameterless constructor explicitly defined
{
    public MyClass2() { }
}

class MyClass3 // only non-parameterless constructor defined
{
    public MyClass3(object parameter) { }
}

class MyClass4 // both parameterless & non-parameterless constructors defined
{
    public MyClass4() { }
    public MyClass4(object parameter) { }
}

interface INewable<T>
    where T : new()
{
}

interface INewableReference<T>
    where T : class, new()
{
}

class Checks
{
    INewable<int> cn1; // ALLOWED: has parameterless ctor
    INewable<string> n2; // NOT ALLOWED: no parameterless ctor
    INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
    INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
    INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
    INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
    INewable<MyClass4> n7; // ALLOWED: has parameterless ctor

    INewableReference<int> nr1; // NOT ALLOWED: not a reference type
    INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
    INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
    INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
    INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}

1
İyi Gösteri. Teşekkürler.
Subhan Ali

15

new (): new () kısıtlamasının belirtilmesi, T tipi parametresiz bir kurucu kullanmalıdır, böylece bir nesne ondan başlatılabilir - bkz. Varsayılan kurucular .

sınıf: T, bir başvuru türü olmalıdır, bu nedenle int, float, double, DateTime veya başka bir yapı (değer türü) olamaz.

public void MakeCars()
{
    //This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
    CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
    var researchEngine = researchLine.MakeEngine();

    //Can instantiate new object of class with default public constructor
    CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
    var productionEngine = productionLine.MakeEngine();
}

public class ProductionEngine { }
public class ResearchEngine
{
    private ResearchEngine() { }
}

public class CarFactory<TEngine> where TEngine : class, new()
{
    public TEngine MakeEngine()
    {
        return new TEngine();
    }
}

6

Yani bu tür Tbir sınıf olmalı ve herhangi bir bağımsız değişken almayan bir yapıcıya sahip .

Örneğin, bunu yapabilmeniz gerekir:

T t = new T();

1
sadece bir kurucu değil, argüman almayan bir kurucu.
NerdFury

@NerdFury: Teşekkürler. Bu önemli bir parça. Düzeltildi.
Evan Mulawski

5

nerede (C # Referansı)

New () Constraint, derleyiciye sağlanan herhangi bir tür bağımsız değişkeninin erişilebilir parametresiz veya varsayılan bir yapıcıya sahip olması gerektiğini bilmesini sağlar

Öyleyse, Tbir sınıf olmalı ve erişilebilir bir parametresiz - veya varsayılan yapıcıya sahip olmalıdır.


4

"Where" den sonra gelen, bildirdiğiniz genel T türü için bir kısıtlamadır, bu nedenle:

  • class , T'nin bir değer türü veya yapı değil, bir sınıf olması gerektiği anlamına gelir.

  • new () , T sınıfının genel parametresiz bir varsayılan kurucu tanımlanmış olması gerektiğini belirtir.


1

Buna genel parametre T'de 'kısıtlama' denir. Bu, T'nin bir referans türü (bir sınıf) olması ve genel bir varsayılan yapıcıya sahip olması gerektiği anlamına gelir.


1

Bu, Generics mekanizmasının bir parçasıdır; burada where anahtar sözcüğü, type parametresi olarak kullanılabilmesi için hangi türlerin uygulanması gerektiğine ilişkin kısıtlamalar ekler.


0

kullanırken sınıfını sınırlamasını ne zaman kullanılacağını kısıtlamaları o sadece Referans türünü kullanabilirsiniz demek, eklenti başka şeydir yeni () , bu kısıtları açısından yazma son şey olmalı bu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.