How to retrieve just the generic items from credentials using CredentialManager

Viewed 74

I am trying to retrieve just the generic credentials from:

using CredentialManagement;

// ...

CredentialSet credentialSet = new CredentialSet();
credentialSet.Load();

// Setup generic credentials subset
CredentialSet genericCredentialSet = (CredentialSet)credentialSet.Where(x => x.Type == CredentialType.Generic);  //if I set this to var it works

I would like to store as CredentialSet (not var). I am getting a cast error with the above code.

Here is how the CredentialSet class begins:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

namespace CredentialManagement
{
    public class CredentialSet: List<Credential>, IDisposable
    {
        bool _disposed;

        public CredentialSet()
        {
        }

        public CredentialSet(string target)
            : this()
        {
            if (string.IsNullOrEmpty(target))
            {
                throw new ArgumentNullException("target");
            }
            Target = target;
        }

        public string Target { get; set; }
...

References: CredentialManagement

1 Answers

Given the code you posted, and so assuming CredentialSet really inherits List<Credential> like the code you posted says, then all you need is to call AddRange(). I.e.

CredentialSet genericCredentialSet = new CredentialSet();

genericCredentialSet.AddRange(credentialSet.Where(x => x.Type == CredentialType.Generic));

Alternatively, if you are up for forking or contributing to the repo where you found CredentialSet, add a new constructor that accepts IEnumerable<Credential>:

public CredentialSet(IEnumerable<Credential> credentials) : base(credentials)
{ }

Which you can then use like:

CredentialSet genericCredentialSet = new CredentialSet(credentialSet.Where(x => x.Type == CredentialType.Generic));

Yet another alternative, and again, only if you are willing to modify the CredentialSet class itself, you could add an explicit operator so that the cast syntax you tried would work:

public class CredentialSet: List<Credential>, IDisposable
{
    // ... other class members ...

    public static explicit operator CredentialSet(IEnumerable<Credential> credentials)
    {
        CredentialSet credentialSet = new CredentialSet();
    
        credentialSet.AddRange(credentials);

        return credentialSet;
    }
}

Naturally, you could combine the constructor alternative with the user-defined conversion operator alternative to simplify the syntax used in the implementation of the user-defined conversion operator.

Regardless of how you implement the user-defined conversion operator, doing so would allow this code you had in the first place to actually compile successfully:

CredentialSet genericCredentialSet = (CredentialSet)credentialSet.Where(x => x.Type == CredentialType.Generic);
Related