diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 358cef1..b277d4e 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -41,12 +41,12 @@ jobs: - name: Install dependencies run: dotnet restore - name: Build - run: dotnet build --configuration Release --no-restore /p:AssemblyVersion=${{ env.GitVersion_SemVer }} /p:FileVersion=${{ env.GitVersion_SemVer }} /p:InformationalVersion=${{ env.GitVersion_SemVer }} + run: dotnet build --configuration Release --no-restore /p:AssemblyVersion=${{ env.GitVersion_AssemblySemVer }} /p:FileVersion=${{ env.GitVersion_AssemblySemFileVer }} /p:InformationalVersion=${{ env.GitVersion_InformationalVersion }} - name: Test run: dotnet test --no-restore --verbosity normal - name: Publish ${{ matrix.runtime }} - run: dotnet publish .//SmartThingsTerminal//SmartThingsTerminal.csproj -o publish/v${{ env.GitVersion_SemVer }}/${{ matrix.runtime }} -c Release -r ${{ matrix.runtime }} -f netcoreapp3.1 /p:PublishSingleFile=true /p:PublishTrimmed=true /p:AssemblyVersion=${{ env.GitVersion_SemVer }} /p:FileVersion=${{ env.GitVersion_SemVer }} /p:InformationalVersion=${{ env.GitVersion_SemVer }} + run: dotnet publish .//SmartThingsTerminal//SmartThingsTerminal.csproj -o publish/v${{ env.GitVersion_SemVer }}/${{ matrix.runtime }} -c Release -r ${{ matrix.runtime }} -f netcoreapp3.1 /p:PublishSingleFile=true /p:PublishTrimmed=true /p:AssemblyVersion=${{ env.GitVersion_AssemblySemVer }} /p:FileVersion=${{ env.GitVersion_AssemblySemFileVer }} /p:InformationalVersion=${{ env.GitVersion_InformationalVersion }} - name: Zip ${{ matrix.runtime }} release uses: papeloto/action-zip@v1 diff --git a/.gitignore b/.gitignore index 4ce6fdd..0fd9d52 100644 --- a/.gitignore +++ b/.gitignore @@ -337,4 +337,6 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb + +Properties/launchSettings.json \ No newline at end of file diff --git a/SmartThingsTerminal.sln b/SmartThingsTerminal.sln index ccf96c7..c7ccf5c 100644 --- a/SmartThingsTerminal.sln +++ b/SmartThingsTerminal.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmartThingsTerminal", "Smar EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8AB9BD79-B877-4441-B6A4-88F1F71EE4E2}" ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + .github\workflows\dotnet-core.yml = .github\workflows\dotnet-core.yml GitVersion.yml = GitVersion.yml LICENSE.txt = LICENSE.txt README.md = README.md diff --git a/SmartThingsTerminal/API/SmartThingsClient.cs b/SmartThingsTerminal/API/SmartThingsClient.cs index 9797751..f10bb58 100644 --- a/SmartThingsTerminal/API/SmartThingsClient.cs +++ b/SmartThingsTerminal/API/SmartThingsClient.cs @@ -70,14 +70,7 @@ public PagedApps GetAllApps() { if (_allApps == null) { - try - { - _allApps = _appsApi.ListApps(); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allApps = _appsApi.ListApps(); } return _allApps; } @@ -88,21 +81,15 @@ public PagedInstalledApps GetAllInstalledApps(string locationId = null) { if (locationId != null) { - try - { - _allInstalledApps = _installedAppsApi.ListInstallations(locationId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allInstalledApps = _installedAppsApi.ListInstallations(locationId); } else { _allInstalledApps = new PagedInstalledApps(); - foreach (var location in GetAllLocations().Items) + var locations = GetAllLocations(); + if (locations?.Items != null) { - try + foreach (var location in locations.Items) { var locationApps = _installedAppsApi.ListInstallations(location.LocationId.ToString()); if (locationApps.Items?.Count > 0) @@ -111,10 +98,6 @@ public PagedInstalledApps GetAllInstalledApps(string locationId = null) _allInstalledApps.Items.AddRange(locationApps.Items); } } - catch (Exception exp) - { - Debug.WriteLine(exp); - } } } } @@ -127,21 +110,15 @@ public PagedSubscriptions GetAllSubscriptions(string appId = null) { if (appId != null) { - try - { - _allSubscriptions = _subscriptionsApi.ListSubscriptions(appId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allSubscriptions = _subscriptionsApi.ListSubscriptions(appId); } else { _allSubscriptions = new PagedSubscriptions(); - foreach (var app in GetAllInstalledApps().Items) + var apps = GetAllInstalledApps(); + if (apps?.Items != null) { - try + foreach (var app in apps.Items) { var appSubscriptions = _subscriptionsApi.ListSubscriptions(app.InstalledAppId.ToString()); if (appSubscriptions.Items?.Count > 0) @@ -150,10 +127,6 @@ public PagedSubscriptions GetAllSubscriptions(string appId = null) _allSubscriptions.Items.AddRange(appSubscriptions.Items); } } - catch (Exception exp) - { - Debug.WriteLine(exp); - } } } } @@ -164,14 +137,7 @@ public async Task GetAllDevicesAsync() { if (_allDevices == null) { - try - { - _allDevices = await _devicesApi.GetDevicesAsync(); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allDevices = await _devicesApi.GetDevicesAsync(); } return _allDevices; } @@ -180,14 +146,7 @@ public PagedDevices GetAllDevices() { if (_allDevices == null) { - try - { - _allDevices = _devicesApi.GetDevices(); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allDevices = _devicesApi.GetDevices(); } return _allDevices; } @@ -196,14 +155,7 @@ public PagedDeviceProfiles GetAllDeviceProfiles() { if (_allDeviceProfiles == null) { - try - { - _allDeviceProfiles = _deviceProfilesApi.ListDeviceProfiles(); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allDeviceProfiles = _deviceProfilesApi.ListDeviceProfiles(); } return _allDeviceProfiles; } @@ -221,14 +173,7 @@ public PagedLocations GetAllLocations() { if (_allLocations == null) { - try - { - _allLocations = _locationsApi.ListLocations(); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allLocations = _locationsApi.ListLocations(); } return _allLocations; } @@ -237,14 +182,7 @@ public async Task GetAllRoomsAsync(string locationId) { if (_allRooms == null) { - try - { - _allRooms = await _roomsApi.ListRoomsAsync(locationId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allRooms = await _roomsApi.ListRoomsAsync(locationId); } return _allRooms; } @@ -255,25 +193,22 @@ public PagedRooms GetAllRooms(string locationId = null) { if (locationId != null) { - try - { - _allRooms = _roomsApi.ListRooms(locationId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allRooms = _roomsApi.ListRooms(locationId); } else { _allRooms = new PagedRooms(); - foreach (var location in GetAllLocations().Items) + var locations = GetAllLocations(); + if (locations!.Items != null) { - var locationRooms = _roomsApi.ListRooms(location.LocationId.ToString()); - if (locationRooms.Items?.Count > 0) + foreach (var location in locations.Items) { - _allRooms.Items ??= new List(); - _allRooms.Items.AddRange(locationRooms.Items); + var locationRooms = _roomsApi.ListRooms(location.LocationId.ToString()); + if (locationRooms.Items?.Count > 0) + { + _allRooms.Items ??= new List(); + _allRooms.Items.AddRange(locationRooms.Items); + } } } } @@ -285,14 +220,7 @@ public PagedScene GetAllScenes(string locationId = null) { if (_allScenes == null) { - try - { - _allScenes = _scenesApi.ListScenes(locationId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allScenes = _scenesApi.ListScenes(locationId); } return _allScenes; } @@ -303,21 +231,15 @@ public PagedRules GetAllRules(string locationId = null) { if (locationId != null) { - try - { - _allRules = _rulesApi.ListRules(locationId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allRules = _rulesApi.ListRules(locationId); } else { _allRules = new PagedRules(); - foreach (var location in GetAllLocations().Items) + var locations = GetAllLocations(); + if (locations!.Items != null) { - try + foreach (var location in locations.Items) { var locationRules = _rulesApi.ListRules(location.LocationId.ToString()); if (locationRules.Items?.Count > 0) @@ -326,10 +248,6 @@ public PagedRules GetAllRules(string locationId = null) _allRules.Items.AddRange(locationRules.Items); } } - catch (Exception exp) - { - Debug.WriteLine(exp); - } } } } @@ -342,21 +260,15 @@ public PagedSchedules GetAllSchedules(string appId = null) { if (appId != null) { - try - { - _allSchedules = _schedulesApi.GetSchedules(appId); - } - catch (Exception exp) - { - Debug.WriteLine(exp); - } + _allSchedules = _schedulesApi.GetSchedules(appId); } else { _allSchedules = new PagedSchedules(); - foreach (var app in GetAllInstalledApps().Items) + var apps = GetAllInstalledApps(); + if (apps?.Items != null) { - try + foreach (var app in apps.Items) { var appSchedules = _schedulesApi.GetSchedules(app.InstalledAppId.ToString()); if (appSchedules.Items?.Count > 0) @@ -365,10 +277,6 @@ public PagedSchedules GetAllSchedules(string appId = null) _allSchedules.Items.AddRange(appSchedules.Items); } } - catch (Exception exp) - { - Debug.WriteLine(exp); - } } } } @@ -388,7 +296,7 @@ protected virtual void Dispose(bool disposing) _allRules = null; _allSchedules = null; _allApps = null; - _allSubscriptions = null; + _allSubscriptions = null; _allInstalledApps = null; _allDeviceProfiles = null; diff --git a/SmartThingsTerminal/Scenario.cs b/SmartThingsTerminal/Scenario.cs index 27fd585..4e361b0 100644 --- a/SmartThingsTerminal/Scenario.cs +++ b/SmartThingsTerminal/Scenario.cs @@ -59,7 +59,7 @@ public virtual void SetErrorView(string message) { X = Pos.Center(), Y = Pos.Center(), - Width = 50, + Width = Dim.Fill(), Height = 5 }; diff --git a/SmartThingsTerminal/Scenarios/Devices.cs b/SmartThingsTerminal/Scenarios/Devices.cs index 8fe921c..93f2169 100644 --- a/SmartThingsTerminal/Scenarios/Devices.cs +++ b/SmartThingsTerminal/Scenarios/Devices.cs @@ -52,13 +52,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Label, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no devices configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewDevices.Keys.ToList()) + ClassListView = new ListView(_viewDevices?.Keys?.ToList()) { X = 0, Y = 0, @@ -68,7 +76,7 @@ public override void Setup() ColorScheme = Colors.TopLevel }; - if (_viewDevices.Keys.Count > 0) + if (_viewDevices?.Keys?.Count > 0) { ClassListView.OpenSelectedItem += (a) => { @@ -127,7 +135,7 @@ public override void Setup() Top.Add(LeftPane, SettingsPane, HostPane); Top.Add(statusBar); - if (_viewDevices.Count > 0) + if (_viewDevices?.Count > 0) { var firstItem = _viewDevices?.FirstOrDefault().Value; if (firstItem != null) diff --git a/SmartThingsTerminal/Scenarios/InstalledApps.cs b/SmartThingsTerminal/Scenarios/InstalledApps.cs index 22b99e9..1f1db86 100644 --- a/SmartThingsTerminal/Scenarios/InstalledApps.cs +++ b/SmartThingsTerminal/Scenarios/InstalledApps.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.DisplayName, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no installed apps"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewInstalledApps.Keys?.ToList()) + ClassListView = new ListView(_viewInstalledApps?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewInstalledApps.Keys.Count > 0) + if (_viewInstalledApps?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -90,7 +98,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewInstalledApps.Count > 0) + if (_viewInstalledApps?.Count > 0) { CurrentView = CreateJsonView(_viewInstalledApps?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Locations.cs b/SmartThingsTerminal/Scenarios/Locations.cs index 1c534c5..6b0165b 100644 --- a/SmartThingsTerminal/Scenarios/Locations.cs +++ b/SmartThingsTerminal/Scenarios/Locations.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Name, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no locations configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewLocations.Keys?.ToList()) + ClassListView = new ListView(_viewLocations?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewLocations.Keys.Count > 0) + if (_viewLocations?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -91,7 +99,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewLocations.Count > 0) + if (_viewLocations?.Count > 0) { CurrentView = CreateJsonView(_viewLocations?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Rooms.cs b/SmartThingsTerminal/Scenarios/Rooms.cs index 758b686..d882a5c 100644 --- a/SmartThingsTerminal/Scenarios/Rooms.cs +++ b/SmartThingsTerminal/Scenarios/Rooms.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Name, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no rooms configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewRooms.Keys?.ToList()) + ClassListView = new ListView(_viewRooms?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewRooms.Keys.Count > 0) + if (_viewRooms?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -90,7 +98,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewRooms.Count > 0) + if (_viewRooms?.Count > 0) { CurrentView = CreateJsonView(_viewRooms?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Rules.cs b/SmartThingsTerminal/Scenarios/Rules.cs index 92b0267..cbb2248 100644 --- a/SmartThingsTerminal/Scenarios/Rules.cs +++ b/SmartThingsTerminal/Scenarios/Rules.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Name, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no rules configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewRules?.Keys.ToList()) + ClassListView = new ListView(_viewRules?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewRules.Keys.Count > 0) + if (_viewRules?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -91,7 +99,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewRules.Count > 0) + if (_viewRules?.Count > 0) { CurrentView = CreateJsonView(_viewRules?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Scenes.cs b/SmartThingsTerminal/Scenarios/Scenes.cs index f44c7c8..6df31ed 100644 --- a/SmartThingsTerminal/Scenarios/Scenes.cs +++ b/SmartThingsTerminal/Scenarios/Scenes.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.SceneName, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no scenes configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewScenes.Keys.ToList()) + ClassListView = new ListView(_viewScenes?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewScenes.Keys.Count > 0) + if (_viewScenes?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -91,7 +99,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewScenes.Count > 0) + if (_viewScenes?.Count > 0) { CurrentView = CreateJsonView(_viewScenes?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Schedules.cs b/SmartThingsTerminal/Scenarios/Schedules.cs index f29d61a..5d2fa30 100644 --- a/SmartThingsTerminal/Scenarios/Schedules.cs +++ b/SmartThingsTerminal/Scenarios/Schedules.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Name, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no schedules configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewSchedules?.Keys.ToList()) + ClassListView = new ListView(_viewSchedules?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewSchedules.Keys.Count > 0) + if (_viewSchedules?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -92,7 +100,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewSchedules.Count > 0) + if (_viewSchedules?.Count > 0) { CurrentView = CreateJsonView(_viewSchedules?.FirstOrDefault().Value?.ToJson()); } diff --git a/SmartThingsTerminal/Scenarios/Subscriptions.cs b/SmartThingsTerminal/Scenarios/Subscriptions.cs index f462cd7..c8fe494 100644 --- a/SmartThingsTerminal/Scenarios/Subscriptions.cs +++ b/SmartThingsTerminal/Scenarios/Subscriptions.cs @@ -51,13 +51,21 @@ public override void Setup() .Select(t => new KeyValuePair(t.Id, t)) .ToDictionary(t => t.Key, t => t.Value); } + else + { + SetErrorView($"You have no subscriptions configured"); + } + } + catch (SmartThingsNet.Client.ApiException exp) + { + SetErrorView($"Error calling API: {exp.Source} {exp.ErrorCode} {exp.Message}"); } catch (System.Exception exp) { - SetErrorView($"No data returned from API:{Environment.NewLine}{exp.Message}"); + SetErrorView($"Unknown error calling API: {exp.Message}"); } - ClassListView = new ListView(_viewSubscriptions?.Keys.ToList()) + ClassListView = new ListView(_viewSubscriptions?.Keys?.ToList()) { X = 0, Y = 0, @@ -67,7 +75,7 @@ public override void Setup() ColorScheme = Colors.TopLevel, }; - if (_viewSubscriptions.Keys.Count > 0) + if (_viewSubscriptions?.Keys?.Count > 0) { ClassListView.SelectedItemChanged += (args) => { @@ -91,7 +99,7 @@ public override void Setup() Top.Add(LeftPane, HostPane); Top.Add(statusBar); - if (_viewSubscriptions.Count > 0) + if (_viewSubscriptions?.Count > 0) { CurrentView = CreateJsonView(_viewSubscriptions?.FirstOrDefault().Value?.ToJson()); } diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index e6add2e..bb4920b 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -551,15 +551,18 @@ public class ListWrapper : IListDataSource { /// public ListWrapper (IList source) { - count = source.Count; - marks = new BitArray (count); - this.src = source; + if (source != null) + { + count = source.Count; + marks = new BitArray(count); + this.src = source; + } } /// /// Gets the number of items in the . /// - public int Count => src.Count; + public int Count => Convert.ToInt32(src?.Count); void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width) {