We went through structs at class and we've been tasked with creating a method inside the struct that changes the fields of an instance compared with another. For example, changing one's name if the other is a manager.
Memory Pool Usage:
Object Size | Allocated | Deallocated | Leaked | Max Stored | Storage Capacity
-------------+-------------+-------------+-------------+-------------+------------------
44 | 1 | 0 | 1 | 0 | 0
52 | 15 | 8 | 7 | 1 | 1
56 | 9 | 9 | 0 | 2 | 2
68 | 6 | 0 | 6 | 0 | 0
72 | 24 | 9 | 15 | 1 | 1
92 | 25 | 17 | 8 | 1 | 1
100 | 1 | 1 | 0 | 1 | 1
152 | 88 | 1 | 87 | 1 | 1
180 | 29 | 24 | 5 | 1 | 1
-------------+-------------+-------------+-------------+-------------+------------------
totals: | 198 | 69 | 129 | 8 | 8
Total constructed: 422
Total destructed: 133
Now, I have this gut feeling that my creation is terrible. I'm not sure about how to actually approach this at all, and it looks like a valuable lesson to learn for real business applications. I would appreciate every tip and trick that is necessary to make these methods, that interact with multiple instances of the struct, better.
答案 0 :(得分:2)
Edit: Clarification
First you should make the mutable properties "ClientId": "MyId",
"ClientName": "MyName",
"AllowedGrantTypes": [ "implicit" ],
"RequireConsent": false,
"AllowedScopes": [ "openid", "profile", "email", "role", "api.write", "api.read", "offline_access" ],
"RedirectUris": [ "https://localhost:4200" ],
"PostLogoutRedirectUris": [ "https://localhost:4200" ],
"LogoutUri": "https://localhost:4200",
"AllowedCorsOrigins": [ "http://localhost:4200", "https://localhost:4200" ],
"AllowOfflineAccess": true,
"AllowAccessTokensViaBrowser": true,
"AccessTokenType": 0
, the constructor accept initial state, and make let openIDImplicitFlowConfiguration = new OpenIDImplicitFlowConfiguration();
openIDImplicitFlowConfiguration.stsServer = environment.stsServer;
openIDImplicitFlowConfiguration.redirect_url = environment.redirect_url;
openIDImplicitFlowConfiguration.client_id = 'MyName';
openIDImplicitFlowConfiguration.response_type = 'id_token token';
openIDImplicitFlowConfiguration.scope = 'openid email profile role api.write api.read offline_access';
openIDImplicitFlowConfiguration.post_logout_redirect_uri = environment.post_logout_redirect_uri;
openIDImplicitFlowConfiguration.start_checksession = false;
openIDImplicitFlowConfiguration.silent_renew = true;
openIDImplicitFlowConfiguration.startup_route = '/home';
openIDImplicitFlowConfiguration.forbidden_route = '/forbidden';
openIDImplicitFlowConfiguration.unauthorized_route = '/unauthorized';
openIDImplicitFlowConfiguration.log_console_warning_active = true;
openIDImplicitFlowConfiguration.log_console_debug_active = true;
openIDImplicitFlowConfiguration.max_id_token_iat_offset_allowed_in_seconds = 10;
openIDImplicitFlowConfiguration.override_well_known_configuration = false;
openIDImplicitFlowConfiguration.override_well_known_configuration_url = environment.well_known_config_url;
openIDImplicitFlowConfiguration.storage = localStorage;
this.oidcSecurityService.setupModule(openIDImplicitFlowConfiguration);
an instance method. This more or less treats each 2017-08-21 11:06:46.910 +12:00 [Information] Request starting HTTP/1.1 GET http://localhost:44345/connect/authorize?response_type=id_token%20token&client_id=AuctionX.Web.Ui.Client.Ng&redirect_uri=http://localhost:4200&scope=openid%20email%20profile%20role%20api.write%20api.read%20offline_access&nonce=N0.008974817642323441503270406807&state=15032704068070.2664008961443083
2017-08-21 11:06:46.929 +12:00 [Information] Executed DbCommand (1ms) [Parameters=[@__get_Item_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [e].[Id], [e].[AccessFailedCount], [e].[ConcurrencyStamp], [e].[Email], [e].[EmailConfirmed], [e].[LockoutEnabled], [e].[LockoutEnd], [e].[NormalizedEmail], [e].[NormalizedUserName], [e].[PasswordHash], [e].[PhoneNumber], [e].[PhoneNumberConfirmed], [e].[SecurityStamp], [e].[TwoFactorEnabled], [e].[UserName]
FROM [AspNetUsers] AS [e]
WHERE [e].[Id] = @__get_Item_0
2017-08-21 11:06:46.938 +12:00 [Information] AuthenticationScheme: "Identity.Application" signed out.
2017-08-21 11:06:46.944 +12:00 [Information] AuthenticationScheme: "Identity.External" signed out.
2017-08-21 11:06:46.950 +12:00 [Information] AuthenticationScheme: "Identity.TwoFactorUserId" signed out.
2017-08-21 11:06:46.953 +12:00 [Information] "Identity.Application" was not authenticated. Failure message: "No principal."
Log files from the Oidc Client
VM543 vendor.bundle.js:441 onWellKnownEndpointsLoaded
VM543 vendor.bundle.js:441 IsAuthorized: id_token isTokenExpired, start silent renew if active
VM543 vendor.bundle.js:441 BEGIN refresh session Authorize
VM543 vendor.bundle.js:441 RefreshSession created. adding myautostate: 15032774526950.18444551521534458
VM543 vendor.bundle.js:441 startRenew for URL:https://localhost:44345/connect/authorize?response_type=id_token%20token&client_id=AuctionX.Web.Ui.Client.Ng&redirect_uri=http://localhost:4200&scope=openid%20email%20profile%20role%20api.write%20api.read%20offline_access&nonce=N0.055432655304242351503277452695&state=15032774526950.18444551521534458
VM543 vendor.bundle.js:441 STS server: https://localhost:44345
VM543 vendor.bundle.js:441 {issuer: "https://localhost:44345", jwks_uri: "https://localhost:44345/.well-known/openid-configuration/jwks", authorization_endpoint: "https://localhost:44345/connect/authorize", token_endpoint: "https://localhost:44345/connect/token", userinfo_endpoint: "https://localhost:44345/connect/userinfo", …}
VM543 vendor.bundle.js:441 AuthWellKnownEndpoints already defined
VM543 vendor.bundle.js:441 BEGIN authorizedCallback, no auth data
VM543 vendor.bundle.js:441 {id_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOT…5P2zqgYNYQOuq36tWm37eLOnZ7PE_TiQoHpX9iEbyaZQQmlPg", access_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOT…pU0eoTqFx9sUbjRw__r8z_-FjaTQH0acMb9K8uKzqOn5dgxnw", token_type: "Bearer", expires_in: "120", scope: "openid%20email%20profile%20role%20api.write%20api.read%20offline_access", …}
VM543 vendor.bundle.js:441 authorizedCallback created, begin token validation
VM543 vendor.bundle.js:441 jwks_uri: https://localhost:44345/.well-known/openid-configuration/jwks
VM543 vendor.bundle.js:126701 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
VM543 vendor.bundle.js:441 validate_id_token_iat_max_offset: 2328 < 10000
VM543 vendor.bundle.js:441 From the server:DsQ3fMYhzDrjDQJPMfqRzg
VM543 vendor.bundle.js:441 client validation not decoded:DsQ3fMYhzDrjDQJPMfqRzg
VM543 vendor.bundle.js:441 AuthorizedCallback token(s) validated, continue
VM543 vendor.bundle.js:441 eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOTFhMjFiYTA3NjVkM2QzNDhjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDMyNzc0NTMsImV4cCI6MTUwMzI3NzU3MywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUiLCJhdWQiOlsiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUvcmVzb3VyY2VzIiwiYXVjdGlvblguYXBpIl0sImNsaWVudF9pZCI6IkF1Y3Rpb25YLldlYi5VaS5DbGllbnQuTmciLCJzdWIiOiI1QkU4NjM1OS0wNzNDLTQzNEItQUQyRC1BMzkzMjIyMkRBQkUiLCJhdXRoX3RpbWUiOjE1MDMyNzU5NzQsImlkcCI6ImxvY2FsIiwicm9sZSI6ImFkbWluIiwic2NvcGUiOlsib3BlbmlkIiwiZW1haWwiLCJwcm9maWxlIiwicm9sZSIsImFwaS53cml0ZSIsImFwaS5yZWFkIiwib2ZmbGluZV9hY2Nlc3MiXSwiYW1yIjpbInB3ZCJdfQ.ZvIho_FnuW_27b_sgLL_nJj_45tqlO4oMSkgFKj8cDObR--4OC1wESgo9jH6vjPR4Gx42DK5iiryaW8X91Yr_X8l-rcwECMacsXR_aZYCVKOC5kORLNHEzSg1ha0vI7EQCn2wuLn_z-ljJGVhxMbc2tI_kCt4abuChA0AryKt0EFCQ_11rvZry_yW49nlUBO_WgkgSB4R5x9MHQiWKlW6UOW-1t790QoARQjyp9WJ0AsHc4xtBjOmLJzOb7kTjp7ND5zrM7QVBK5HOewaV4fL7cVjWGXEZmH9m9D3pU0eoTqFx9sUbjRw__r8z_-FjaTQH0acMb9K8uKzqOn5dgxnw
VM543 vendor.bundle.js:441 eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOTFhMjFiYTA3NjVkM2QzNDhjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDMyNzc0NTMsImV4cCI6MTUwMzI3NzU0MywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUiLCJhdWQiOiJBdWN0aW9uWC5XZWIuVWkuQ2xpZW50Lk5nIiwibm9uY2UiOiJOMC4wNTU0MzI2NTUzMDQyNDIzNTE1MDMyNzc0NTI2OTUiLCJpYXQiOjE1MDMyNzc0NTMsImF0X2hhc2giOiJEc1EzZk1ZaHpEcmpEUUpQTWZxUnpnIiwic2lkIjoiMWJkNjQ0YmVhMjQwZjM1MDc2YzQ5NzVjOTg0ZjI1N2IiLCJzdWIiOiI1QkU4NjM1OS0wNzNDLTQzNEItQUQyRC1BMzkzMjIyMkRBQkUiLCJhdXRoX3RpbWUiOjE1MDMyNzU5NzQsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.pExwBcxTQiT2nY38l5f6ZGNs4gzLTYZlUEO6sDl_Q2fPmzjppKn-7yU8bhjCy6xZKKuOT3pRO3JmZFEln1CDBfJqTsOg4UH8tu0MIIeMkiIBwjMooqb-ocN6JPwkrr-CuSk90xsQmGPqdaSRLC7IHFQ2VPq5Ic7b9Jd4CXIDZQbBKdR2PEC8n2Rfl-ayDOEXzOni8ylQ5ksu28eRicv7-HYimnF3Xc63xiBIC1NH4OofxQoqQRdBL2j8OJDKXQY6oDZxUNBLsIf1-jnM_MUTnr4tHoiX-XIhbZuTa5P2zqgYNYQOuq36tWm37eLOnZ7PE_TiQoHpX9iEbyaZQQmlPg
VM543 vendor.bundle.js:441 storing to storage, getting the roles
VM543 vendor.bundle.js:441 onWellKnownEndpointsLoaded
VM543 vendor.bundle.js:441 IsAuthorized: id_token isTokenExpired, start silent renew if active
VM543 vendor.bundle.js:441 BEGIN refresh session Authorize
VM543 vendor.bundle.js:441 RefreshSession created. adding myautostate: 15032775466960.9369647619628338
VM543 vendor.bundle.js:441 startRenew for URL:https://localhost:44345/connect/authorize?response_type=id_token%20token&client_id=AuctionX.Web.Ui.Client.Ng&redirect_uri=http://localhost:4200&scope=openid%20email%20profile%20role%20api.write%20api.read%20offline_access&nonce=N0.223876239755147031503277546696&state=15032775466960.9369647619628338
VM543 vendor.bundle.js:441 STS server: https://localhost:44345
VM543 vendor.bundle.js:441 {issuer: "https://localhost:44345", jwks_uri: "https://localhost:44345/.well-known/openid-configuration/jwks", authorization_endpoint: "https://localhost:44345/connect/authorize", token_endpoint: "https://localhost:44345/connect/token", userinfo_endpoint: "https://localhost:44345/connect/userinfo", …}
VM543 vendor.bundle.js:441 AuthWellKnownEndpoints already defined
VM543 vendor.bundle.js:441 BEGIN authorizedCallback, no auth data
VM543 vendor.bundle.js:441 {id_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOT…y0UvzWAIigtnoy8ho-RvIHCVLfFNdrS_YockJLRhwZZHtOgVg", access_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOT…Q4CSsXVqa58bI7tROqruKxn9bb3q7zPIV-KSTOhXGAFo7ZN7Q", token_type: "Bearer", expires_in: "120", scope: "openid%20email%20profile%20role%20api.write%20api.read%20offline_access", …}
VM543 vendor.bundle.js:441 authorizedCallback created, begin token validation
VM543 vendor.bundle.js:441 jwks_uri: https://localhost:44345/.well-known/openid-configuration/jwks
VM543 vendor.bundle.js:126701 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
VM543 vendor.bundle.js:441 validate_id_token_iat_max_offset: 2334 < 10000
VM543 vendor.bundle.js:441 From the server:VBff-XldgCju7j-ghbcK3g
VM543 vendor.bundle.js:441 client validation not decoded:VBff-XldgCju7j-ghbcK3g
VM543 vendor.bundle.js:441 AuthorizedCallback token(s) validated, continue
VM543 vendor.bundle.js:441 eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOTFhMjFiYTA3NjVkM2QzNDhjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDMyNzc1NDcsImV4cCI6MTUwMzI3NzY2NywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUiLCJhdWQiOlsiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUvcmVzb3VyY2VzIiwiYXVjdGlvblguYXBpIl0sImNsaWVudF9pZCI6IkF1Y3Rpb25YLldlYi5VaS5DbGllbnQuTmciLCJzdWIiOiI1QkU4NjM1OS0wNzNDLTQzNEItQUQyRC1BMzkzMjIyMkRBQkUiLCJhdXRoX3RpbWUiOjE1MDMyNzU5NzQsImlkcCI6ImxvY2FsIiwicm9sZSI6ImFkbWluIiwic2NvcGUiOlsib3BlbmlkIiwiZW1haWwiLCJwcm9maWxlIiwicm9sZSIsImFwaS53cml0ZSIsImFwaS5yZWFkIiwib2ZmbGluZV9hY2Nlc3MiXSwiYW1yIjpbInB3ZCJdfQ.Xy1X3CeEaTYAWNKkYrIKKhZiEYkRnGJve1pP2kDO5qRg5-Qe-g9h-0BB-j5TeXE1VIrBOJ-1vr6Vkr28jfyAz7t02rHnK9Vs94xFc2H8UNcF98YBT-7GKqRd-FB1L3lQqtZWMku4b01qmIPSjUThzShcdgrbOsIpwdxC3UB-Ziram6EfUme10Wpb2J1vto7rEKcurQ6LZI3645x0rTlGS2fXU7x0UQxfxhAX9VNYwAreT8T2-O4mLzr9Ejbd-kMEfXNALIUUJ3KKRmGOGCHM5fwHzsuX67gIqJXueQ4CSsXVqa58bI7tROqruKxn9bb3q7zPIV-KSTOhXGAFo7ZN7Q
VM543 vendor.bundle.js:441 eyJhbGciOiJSUzI1NiIsImtpZCI6IjJlY2ZkYTVhMmI1OTAwOTFhMjFiYTA3NjVkM2QzNDhjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDMyNzc1NDcsImV4cCI6MTUwMzI3NzYzNywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDUiLCJhdWQiOiJBdWN0aW9uWC5XZWIuVWkuQ2xpZW50Lk5nIiwibm9uY2UiOiJOMC4yMjM4NzYyMzk3NTUxNDcwMzE1MDMyNzc1NDY2OTYiLCJpYXQiOjE1MDMyNzc1NDcsImF0X2hhc2giOiJWQmZmLVhsZGdDanU3ai1naGJjSzNnIiwic2lkIjoiMWJkNjQ0YmVhMjQwZjM1MDc2YzQ5NzVjOTg0ZjI1N2IiLCJzdWIiOiI1QkU4NjM1OS0wNzNDLTQzNEItQUQyRC1BMzkzMjIyMkRBQkUiLCJhdXRoX3RpbWUiOjE1MDMyNzU5NzQsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.f-PzKxDafEIRPIz_qL_xtbI4QlDybyyRWMhnxUaNzOS1SJGVLVY1zpx89Y0MHlSe8NSZgtBOieB_Wr52nKZLm85ItMOCSpr5I5uZBi_mdufBEJWzOfbcnPT53pvpETwBVxSAOJvJXq-XxC-rxCeoHs7xd57M57RWa_Wla_rgh2-dVdscHHxA7fKDToEM_SpLgmFlI4QWV3DnMtkNWVzXkSNq1Iv5AOvtfI_j5Dz5XgsJAoyI1vWQHZqRuNO8_TK0g2oudvfv-xji1Uc_oFA_0rEdfoacNoyAwe4vky0UvzWAIigtnoy8ho-RvIHCVLfFNdrS_YockJLRhwZZHtOgVg
VM543 vendor.bundle.js:441 storing to storage, getting the roles
VM543 vendor.bundle.js:441 onWellKnownEndpointsLoaded
home:1 Refused to display 'https://localhost:44345/account/login?returnUrl=%2Fconnect%2Fauthorize%2Flogin%3Fresponse_type%3Did_token%2520token%26client_id%3DAuctionX.Web.Ui.Client.Ng%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A4200%26scope%3Dopenid%2520email%2520profile%2520role%2520api.write%2520api.read%2520offline_access%26nonce%3DN0.481244061017480631503277824820%26state%3D15032778248200.2571680787467199' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
like a database record with access control, creating a simpler relationship.
private set;
Using it thus becomes:
EditInfo
Secondly, unless your instructor forbade you from using Employee
, you should make it a class and get rid of all the public class Employee
{
public Employee(string firstName, string lastName, bool isManager, ...)
{
FirstName = firstName;
LastName = lastName;
IsManager = isManager;
// remaining properties...
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public bool IsManager { get; private set; }
// remaining properties...
public void Edit(Employee requester)
{
if (requester.IsManager) {
// query input from the user, make changes, and notify the user.
} else {
// notify the user that he doesn't have permission to edit this employee.
}
}
}
declarations. var manager = new Employee("Your", "Boss", isManager: true);
var sheep = new Employee("John", "Doe", isManager: false);
sheep.Edit(manager); // Essentially says "edit sheep using manager as permission".
and class
are very useful in the right cirumstances, but unless you're aware of the tradeoffs and code rigorously, its too easy to introduce a bug that will be difficult to reason about considering your experience level.
Classes don't automatically make copies or require the ref
keyword. Structs on the other hand do make copies without struct
, thus semantically requiring(but not enforcing) it at every call site that makes modifications to it. This has further implications which you may not be aware of. Consider properties. Properties cannot be passed with ref, only locals, fields, and array elements. Unfortunately that means it's currently impossible to pass a struct property by ref(though subject to change in a future C# version). This will likely bite you down the road.
In summary, prefer classes in C# unless you have a good reason to use structs(i.e. GC performance, very special purpose types). Above all, aim for readability.