Improving function when used from another class The title could probably be better, but in any case here goes.

I am having a bit of a problem understanding how to move methods/functions to other classes to organize things.

So, I have moved a method of sorts, but as I am skeptical of it, I would like to get it reviewed and hear opinions on what can be improved.

Here is the method ran from the default class:

private void GetAudioDevices()
{
    foreach (MMDevice device in Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active))
    {
        comboBox1.Items.Add(device.FriendlyName);
        Console.WriteLine("{0}, {1}", device.FriendlyName, device.State);
    }
    PlayBackDevices = Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
    for (waveInDevice = 0; waveInDevice &lt; NAudio.Wave.WaveIn.DeviceCount; waveInDevice++)
    {
        DeviceInfo = WaveIn.GetCapabilities(waveInDevice);
        AudioDevices.Items.Add(DeviceInfo.ProductName);
    }
    if (AudioDevices.Items.Count &gt; 0)
        AudioDevices.SelectedIndex = 0;

    AudioDevices.Items.Add("Wasapi Loopback");
    ListenAudioAgain = false;
    AudioDevice = AudioDevices.SelectedItem.ToString();
    comboBox1.SelectedItem = VoiceChatClass.Enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia).ToString();
}


Here it is when ran from a separate class:

public static void GetAudioDevices(ComboBox comboBox1, ComboBox AudioDevices)
{
    foreach (MMDevice device in VoiceChatClass.Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active))
    {
        comboBox1.Items.Add(device.FriendlyName);
        Console.WriteLine("{0}, {1}", device.FriendlyName, device.State);
    }
    VoiceChatClass.PlayBackDevices = VoiceChatClass.Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
    for (VoiceChatClass.waveInDevice = 0; VoiceChatClass.waveInDevice &lt; NAudio.Wave.WaveIn.DeviceCount; VoiceChatClass.waveInDevice++)
    {
        VoiceChatClass.DeviceInfo = NAudio.Wave.WaveIn.GetCapabilities(VoiceChatClass.waveInDevice);
        AudioDevices.Items.Add(VoiceChatClass.DeviceInfo.ProductName);
    }
    if (AudioDevices.Items.Count &gt; 0)
        AudioDevices.SelectedIndex = 0;

    AudioDevices.Items.Add("Wasapi Loopback");
    VoiceChatClass.ListenAudioAgain = false;
    VoiceChatClass.AudioDevice = AudioDevices.SelectedItem.ToString();
    comboBox1.SelectedItem = VoiceChatClass.Enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia).ToString();
        Console.WriteLine(VoiceChatClass.Enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia));
}


I am having difficulties understanding how to use static and non-static variables.

I just want to move it to a separate class for organization reasons. I know you can do it with partial classes, but sadly they are a bit "bugged" when used with a form in Visual Studio, as the design form will go away and stuff.  It just gets unnecessarily complicated so to speak.

So anyway, what are your opinions upon viewing this?  Is there a way to make it simpler?  Are there any issues that have come up?
It seems to me like you are really asking about static vs non-static


static


This means that your instance or instance variable is class-bound. No matter how many objects you make, they will all share the same static variable. Take this class with a static variable called InstanceID. What it will do is increment the static variable by one for each object you create

public class StaticVSNonStatic
{
    private static int InstanceID = 0;

    public StaticVSNonStatic()
    {
        InstanceID++;
    }

    public int GetInstanceID() { return InstanceID; }
}


so say that you later create N number of StaticVSNonStatic objects it won't matter which one you call because they will all share the same variable and will output the same value.

StaticVSNonStatic s1 = new StaticVSNonStatic();
StaticVSNonStatic s2 = new StaticVSNonStatic();
StaticVSNonStatic s3 = new StaticVSNonStatic();

var value = s1.GetInstanceID(); // this will be 3


And if we create any more object of StaticVSNonStatic the InstanceID value will just keep on incrementing. 


non-static


Simply means a variable or an object that is not declared as static. A variable that is not static is instance-bound, and for each instance you create they will have their own variable. So if we go back to the class above and remove the static keyword the value will always be 1 regardless of which object you are accessing and regardless of how many objects you have.


  So anyway, what are your opinions upon viewing this? Is there a way to make it simpler? Are there any issues that have come up?


It seems like you do not quite understand how and when to create a class to represent an object and you don't fully understand static. But it's ok, OOP is a hard design pattern to grasp. Let's take a look of what you can improve and what makes me say that you don't understand it...

In a few places in your "seperate class" example you write

VoiceChatClass.ListenAudioAgain = false;
VoiceChatClass.AudioDevice = AudioDevices.SelectedItem.ToString();
VoiceChatClass.DeviceInfo =  Audio.Wave.WaveIn.GetCapabilities(VoiceChatClass.waveInDevice);
VoiceChatClass.PlayBackDevices = VoiceChatClass.Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);


Which are all static variables which you are invoking, but to me it looks like this should be non-static because to me it looks like you should be able to have multiple "unique" VoiceChat objects. 

e.g., you should be able to have one VoiceChat object which has ListenAudioAgain set to false and another VoiceChat object which has it set to true. Or you could have two different VoiceChats with different PlayBackDevices. This is the way it should be but is impossible in your case because of the static.

. The first step in making sure we can have multiple "unique" VoiceChat objects is by removing the static keyword from the class, which should give you a class that looks something like this (remember that this is a guess since I can't actually know what the class looks like):

public class VoiceChat
{
    public bool ListenToAudioAgain { get; set; }
    public string AudioDevice { get; set; }
    public DeviceInfo DeviceInfo { get; set; }
    public PlayBackDevices[] PlayBackDevices { get; set; }
}


And you would use this (in your second example) by first creating (or passing it in by your parameters) an instance of the VoiceChat class. In this case we named the instance to voiceChat, and then we access its instance members.

public static void GetAudioDevices(ComboBox comboBox1, ComboBox AudioDevices)
{
    VoiceChat voiceChat = new VoiceChat()

    foreach (MMDevice device in voiceChat.Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active))
    {
        comboBox1.Items.Add(device.FriendlyName);
        Console.WriteLine("{0}, {1}", device.FriendlyName, device.State);
    }

    voiceChat.PlayBackDevices = voiceChat.Enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

    for (voiceChat.waveInDevice = 0; voiceChat.waveInDevice &lt; NAudio.Wave.WaveIn.DeviceCount; VoiceChatClass.waveInDevice++)
    {
        voiceChat.DeviceInfo = NAudio.Wave.WaveIn.GetCapabilities(VoiceChatClass.waveInDevice);
        AudioDevices.Items.Add(voiceChat.DeviceInfo.ProductName);
    }

    if (AudioDevices.Items.Count &gt; 0) {
        AudioDevices.SelectedIndex = 0;
    }

    AudioDevices.Items.Add("Wasapi Loopback");

    voiceChat.ListenAudioAgain = false;
    voiceChat.AudioDevice = AudioDevices.SelectedItem.ToString();

    comboBox1.SelectedItem = voiceChat.Enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia).ToString();

    Console.WriteLine(voiceChat.Enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia));
}


This is a quick introduction so if there's something unclear just let me know and I'll try to clarify.