Non en lecture seule alternative pour les types anonymes
En C#, un type anonyme peut être comme suit:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
//Do stuff
}
}
Cependant, le suivant ne compile pas:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
myVar.b = true;
}
}
C'est parce que myVar les champs sont en lecture seule et ne peuvent être cédés. Il semble vouloir faire quelque chose comme ce dernier est assez commun; peut-être la meilleure solution que j'ai vu est de définir une structure en dehors de la méthode.
Cependant, est-il vraiment pas d'autre façon de faire le bloc ci-dessus travail? La raison pour laquelle il me dérange, c'est, myVar est une variable locale de ce domaine, de sorte qu'il semble qu'il ne devrait être appelé à l'intérieur de la méthode qui l'utilise. En outre, besoin de place la structure en dehors de la méthode peut faire la déclaration d'un objet très éloigné de son utilisation, en particulier dans une longue méthode.
Mettre une autre manière, est-il une solution de rechange pour les types anonymes qui va me permettre de définir un "struct" comme ceci (je me rends compte struct existe en C#, et doit être définie en dehors d'une méthode) sans en faire lecture seule? Si non, est-il quelque chose de fondamentalement mauvais vouloir pour ce faire, et que je devrais être en utilisant une approche différente?
- Les types anonymes sont conçus, pour une fois seulement, une utilisation rapide. Si votre utilisation est plus compliqué que cela, il y a tous les readsons pour créer un type nommé.
Vous devez vous connecter pour publier un commentaire.
Pas, vous devrez créer votre propre classe ou structure pour ce faire (de préférence une classe, si vous voulez qu'il soit mutable - mutable structures sont horribles).
Si vous n'avez pas de soins sur
Equals
/ToString
/GetHashCode
implémentations, c'est assez facile:(J'aurais quand même utiliser les propriétés plutôt que de champs, pour diverses raisons.)
Personnellement j'ai l'habitude de me surprends à vouloir un immuable type qui je peux passer entre des méthodes, etc - je veux un nom de version de l'existant anonyme de type de fonctionnalité...
this
ou des propriétés que l'accès à l'extérieur entités, un "immuable" struct et un "mutable" on va être impossible à distinguer de n'importe quel code qui n'est pas directement de tenter de modifier ses champs. Je peux voir des arguments à l'encontre de la tentative de modifier struct champs si on ne sait pas ce que l'on fait, mais ce n'est pas un argument pour avoir des structures en interdire telle modification.this
? Pouvez-vous m'indiquer la description de tout (non-ce-écrit) les problèmes que vous avez vu qui ne sont pas clairement les résultats de quelqu'un qui n'a pas de comprendre comment les structures de travail (par exemple, quelque chose de saisissant à partir d'une collection, la modification de cette chose, et allègrement s'attendait à une mise à jour de la collection--quelque chose qui peut ou ne peut pas travailler avec des classes, et ne sera certainement pas travailler avec des structures)?thing=Collection[index]; thing.someProperty=whatever;
va modifier en toute sécuritéCollection[index].someProperty;
à moins qu'il ait examiné assez de code pour s'assurer que c'est le cas. Pourquoi devrait-on s'attendre à ce que d'un programmeur qui ne comprennent pas les structures seraient compétents pour reconnaître si oui ou non le code ci-dessus serait un moyen sûr de mettre à jour une propriété de classe-instance de type? Comme pour les personnes ayant "mutable struct mal" sur stack overflow, ils semblent tous se divisent en trois catégories:this
mutations qui ne fonctionnent pas, ...this
sans une bonne raison."; le deuxième problème n'est pas fait pire avec les structures mutables que immuables; la le troisième problème est beaucoup moins de mal avec les structures mutables qu'avec mutable classes.this
; nous sommes d'accord que ceux qui sont problématiques. Notre seul point de désaccord, c'est que je pense que les structures devraient, dans de nombreux cas, exposer des champs publics, puisque l'on est autorisé à écrire des champs publics, dans les seuls cas où l'on serait autorisé à direstructVar = structVar.withField(whatever);
, et avec essentiellement la même sémantique, sauf que le champ d'écriture sera plus rapide, de différents domaines peuvent être écrits dans différents threads sans interférence, et même-champ écrit peut être résolu parInterlocked
.Pas. Vous aurez à faire un type nominal.
Non, c'est raisonnable fonctionnalité que nous avons pris en considération avant.
Je note que dans Visual Basic, les types anonymes sont mutable si vous le souhaitez.
La seule chose qui est vraiment "fondamentalement mauvais" sur une mutable type anonyme, qu'il serait dangereux pour l'utiliser comme une clé de hachage. Nous avons conçu les types anonymes avec les hypothèses que (1) vous allez utiliser les touches dans equijoins dans une requête LINQ de compréhensions, et (2) dans LINQ-to-Objets et d'autres implémentations, les jointures seront mises en œuvre à l'aide de tables de hachage. Par conséquent, les types anonymes devraient être utiles en tant que clés de hachage, et mutable clés de hachage sont dangereux.
Dans Visual Basic, le GetHashCode mise en œuvre ne consomme aucune information de champs mutables des types anonymes. Si c'est un compromis raisonnable, nous avons simplement décidé qu'en C# le supplément de complexité n'en valent pas la peine.
Vous ne pourrez pas obtenir le bon syntaxe d'initialisation, mais le
ExpandoObject
classe introduit dans .NET 4 servirait comme une solution viable.ExpandoObject
prend en charge un nom, tapé, null valeur de la propriété (puisqu'il s'agit seulement d'un dictionnaire, et tous lesnull
valeurs typées), tandis qu'un type anonyme n'.En C# 7 on peut tirer parti de nommé tuples de faire le tour:
Pour les types ci-dessus de l'opération, vous devez définir votre propre mutable STRUCT. Mutable structures peuvent poser un casse-tête pour les rédacteurs du compilateur comme Eric Lippert, et il y a quelques malheureux limitations comment .net poignées, mais la sémantique de mutables "Plain Old Données" des structures (structures dont tous les champs sont publiques, et la seule fonction publique qui écrire
this
sont les constructeurs, ou sont appelés exclusivement à partir de constructeurs) offre la mesure de la sémantique que ce qui peut être réalisée par des classes.Par exemple, considérez les points suivants:
En supposant que il n'y a pas de code non sécurisé et que le passé-les délégués peuvent être appelés, et sera de retour en un temps fini, ce sera
test()
retour? Le fait queFoo
est une structure avec un champ publicbar
est suffisante pour répondre à la question: il sera de retour 9, indépendamment de ce qui apparaît dans la déclaration deFoo
, et indépendamment de ce que les fonctions sont passés dansproc1
etproc2
. SiFoo
étaient une classe, il faudrait examiner chaqueAction<Foo[]>
etAction<Foo>
qui existe ou existera jamais, de savoir ce quetest()
serait de retour. La détermination de cetteFoo
est une structure publique de champbar
semble beaucoup plus facile que l'examen de tout passé et de l'avenir des fonctions qui pourraient se passer dans.Struct méthodes qui modifient
this
sont traitées particulièrement mal .net, donc si on a besoin d'utiliser une méthode pour modifier un struct, c'est presque certainement préférable d'utiliser l'un de ces modèles:que le motif:
Pourvu que l'on emploie l'approche ci-dessus pour struct-la modification des modèles, cependant, mutable structures ont l'avantage de permettre de code qui est à la fois plus efficace et plus facile à lire que des structures immuables, ni immuable classes, et est beaucoup moins de problèmes vulnérables que mutable classes. Pour les choses qui représentent une agrégation de valeurs, sans identité, à l'extérieur les valeurs qu'elles contiennent, mutable types de classes sont souvent les pires représentation possible.
Object
.