Answer-ID
  • Întrebări
  • Tag-uri
  • Categorii
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
Rob Cooper
Rob Cooper

Verificarea tipului general

Is there a way to enforce/limit the types that are passed to primitives? (bool, int, string, etc.)

Acum, știu că puteți limita parametrul de tip generic la o implementare de tip sau de interfață prin intermediul clauzei unde . Cu toate acestea, acest lucru nu se potrivește facturii pentru primitive (AFAIK), deoarece nu toate au un teren comun (cu excepția obiectului înainte de cineva spune!: P).

Deci, gândurile mele actuale sunt doar să-mi sparg dinții și să fac o instrucțiune comutator și să arunc o eroare ArgumentException la eșec.


EDIT 1:

Doar pentru a clarifica:

Definiția codului ar trebui să fie:

public class MyClass ....

Și instanțierea:

MyClass = new MyClass();//Legal
MyClass = new MyClass();//Legal
MyClass = new MyClass();//Illegal
MyClass = new MyClass();//Illegal (but looks awesome!)

EDIT 2

@Jon Limjap - Punct bun, și ceva ce mă gândeam deja .. Sunt sigur că există o metodă generică care poate fi utilizată pentru a determina dacă tipul este de valoare sau tip de referință.

Acest lucru ar putea fi util pentru a elimina instantaneu o mulțime de obiecte pe care nu vreau să le tratez (dar atunci trebuie să vă faceți griji cu privire la structurile care sunt utilizate, cum ar fi Dimensiune ) .. Problema interesantă nu? :)

Aici este:

where T : struct

Luat de la MSDN .


Sunt curios .. Ar putea fi făcut în. NET 3.x folosind metode de extensie? Creați o interfață și implementați interfața în metodele de extensie (care ar fi probabil mai puțin curat decât un comutator de grăsime bit). În plus, dacă mai trebuie să extindeți mai târziu la oricare tip personalizat ușor, aceștia pot implementa aceeași interfață, fără modificări necesare pentru codul de bază.

Voi ce credeți?

Vestea trista este ca lucrez in cadrul 2! : D


EDIT 3

Acest lucru a fost atât de simplu ca urmare a Pointerul lui Jon Limjaps .. Atât de simplu vreau aproape să plâng, dar este minunat deoarece codul funcționează ca un farmec!

Deci, iată ce am făcut (veți râde!):

Codul a fost adăugat clasei generice

bool TypeValid()
{
   //Get the TypeCode from the Primitive Type
    TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));

   //All of the TypeCode Enumeration refer Primitive Types
   //with the exception of Object and Empty (Null).
   //Since I am willing to allow Null Types (at this time)
   //all we need to check for is Object!
    switch (code)
    {
        case TypeCode.Object:
            return false;
        default:
            return true;
    }
}

Apoi o mică metodă de utilitate pentru a verifica tipul și a arunca o excepție,

private void EnforcePrimitiveType()
{
    if (!TypeValid())
        throw new InvalidOperationException(
            "Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name + 
            "' - this Class is Designed to Work with Primitive Data Types Only.");
}

Tot ce trebuie făcut este să apelați EnforcePrimitiveType () în constructorii de clase. Treaba făcuta! :-)

Singurul dezavantaj, aruncă doar o excepție la timpul de execuție (evident), mai degrabă decât timpul de design .. Dar asta nu este mare lucru și ar putea fi luat cu utilități ca FxCop (pe care nu o folosim la serviciu).

Mulțumiri speciale lui Jon Limjap pe aceasta!

71 2008-08-12T15:07:40+00:00 8
Programare
c#
generics
type-safety
primitive
Comentarii la întrebare (0)
Lars Mæhlum
12 august 2008 в 7:11
2008-08-12T19:11:58+00:00
Mai mult
Sursă
Editează
#8945
public class Class1 where GenericType : struct
{
}

Aceasta părea să facă treaba.

0
0
Comentarii (0)
JoshL
12 august 2008 в 7:21
2008-08-12T19:21:05+00:00
Mai mult
Sursă
Editează
#8954

Use a custom FxCop rule that flags undesirable usage of MyClass<>.

0
0
Comentarii (0)
Jon Limjap
12 august 2008 в 7:21
2008-08-12T19:21:44+00:00
Mai mult
Sursă
Editează
#8956

Primitivele par să fie specificate în TypeCode enumerare:

Poate că există o modalitate de a afla dacă un obiect conține codul TypeCode enum fără a fi nevoie să îl deplasați la un anumit obiect sau să apelați GetType () sau typeof () ?

Update It was right under my nose. The code sample there shows this:

static void WriteObjectInfo(object testObject)
{
    TypeCode    typeCode = Type.GetTypeCode( testObject.GetType() );

    switch( typeCode )
    {
        case TypeCode.Boolean:
            Console.WriteLine("Boolean: {0}", testObject);
            break;

        case TypeCode.Double:
            Console.WriteLine("Double: {0}", testObject);
            break;

        default:
            Console.WriteLine("{0}: {1}", typeCode.ToString(), testObject);
            break;
        }
    }
}

E încă un comutator urât. Dar este un loc bun pentru a începe!

0
0
Comentarii (0)
Keith
12 august 2008 в 7:43
2008-08-12T19:43:37+00:00
Mai mult
Sursă
Editează
#8980

Destul de mult ce a spus @Lars:

//Force T to be a value (primitive) type.
public class Class1 where T: struct

//Force T to be a reference type.
public class Class1 where T: class

//Force T to be a parameterless constructor.
public class Class1 where T: new()

Toate lucrările în .NET 2, 3 și 3.5.

0
0
Comentarii (0)
Doug McClean
16 septembrie 2008 в 9:52
2008-09-16T09:52:05+00:00
Mai mult
Sursă
Editează
#69673

Dacă puteți tolera utilizarea metodelor din fabrică (în locul constructorilor MyClass pe care i-ați cerut), puteți face întotdeauna ceva de genul:

class MyClass
{
  private readonly T _value;

  private MyClass(T value) { _value = value; }

  public static MyClass FromInt32(int value) { return new MyClass(value); }
  public static MyClass FromString(string value) { return new MyClass(value); }
 //etc for all the primitive types, or whatever other fixed set of types you are concerned about
}

A problem here is that you would need to type MyClass.FromInt32, which is annoying. There isn't a very good way around this if you want to maintain the private-ness of the constructor, but here are a couple of workarounds:

  • Create an abstract class MyClass. Make MyClass inherit from MyClass and nest it within MyClass. Move the static methods to MyClass. This will all the visibility work out, at the cost of having to access MyClass as MyClass.MyClass.
  • Use MyClass as given. Make a static class MyClass which calls the static methods in MyClass using MyClass (probably using the appropriate type each time, just for giggles).
  • (Easier, but certainly weird) Make an abstract type MyClass which inherits from MyClass. (For concreteness, let's say MyClass.) Because you can call static methods defined in a base class through the name of a derived class, you can now use MyClass.FromString.

Acest lucru vă oferă o verificare statică în detrimentul mai multor scrisori.

Dacă sunteți mulțumit de verificarea dinamică, aș folosi câteva variante ale soluției TypeCode de mai sus.

0
0
Comentarii (0)
Vivek
20 octombrie 2008 в 2:38
2008-10-20T02:38:42+00:00
Mai mult
Sursă
Editează
#217079

Puteți simplifica metoda EnforcePrimitiveType utilizând typeof (PrimitiveDataType) .IsPrimitive . Am pierdut ceva?

0
0
Comentarii (0)
Matthew Boehlig
26 martie 2009 в 8:08
2009-03-26T20:08:12+00:00
Mai mult
Sursă
Editează
#686709

@Rob, Enum va aluneca prin funcția TypeValid , deoarece TypeCode este Integer . Am actualizat funcția de verificat și pentru Enum .

Private Function TypeValid() As Boolean
    Dim g As Type = GetType(T)
    Dim code As TypeCode = Type.GetTypeCode(g)

    ' All of the TypeCode Enumeration refer Primitive Types
    ' with the exception of Object and Empty (Nothing).
    ' Note: must also catch Enum as its type is Integer.
    Select Case code
        Case TypeCode.Object
            Return False
        Case Else
            ' Enum's TypeCode is Integer, so check BaseType
            If g.BaseType Is GetType(System.Enum) Then
                Return False
            Else
                Return True
            End If
    End Select
End Function
0
0
Comentarii (0)
Michael Mortensen
27 iulie 2012 в 6:47
2012-07-27T18:47:55+00:00
Mai mult
Sursă
Editează
#11690199

Având o provocare similară, mă întrebam cum v-ați simțit despre Interfața IConvertible . Aceasta permite ceea ce solicită solicitantul și vă puteți extinde cu propriile implementări.

Exemplu:

    public class MyClass
    where TKey : IConvertible
{
   //class intentionally abbreviated
}

Mă gândesc la asta ca la o soluție, cu toate că multe dintre cele sugerate făceau parte și din selecția mea.

Preocuparea mea este - cu toate acestea - este înșelătoare pentru dezvoltatorii potențiali care folosesc clasa ta?

Noroc - și mulțumiri.

0
0
Comentarii (0)
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
ID
KO
RU
© Answer-ID 2021
Sursă
https://stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire