How to Use Reflection in C# to Dynamically Invoke Methods

Reflection in C# allows you to inspect and interact with types dynamically at runtime. It is useful for scenarios like plugin systems, dependency injection, and working with unknown assemblies.

Getting Started with Reflection

To use reflection, include the System.Reflection namespace:

using System;
using System.Reflection;

Invoking a Method Dynamically

You can use reflection to call methods on an object when you don't know the method name at compile time.

class Sample
{
    public void SayHello() => Console.WriteLine("Hello from Reflection!");
}

var sample = new Sample();
MethodInfo method = typeof(Sample).GetMethod("SayHello");
method?.Invoke(sample, null);
// Output: Hello from Reflection!

Invoking Methods with Parameters

If a method requires parameters, pass them as an object array:

class MathOperations
{
    public int Add(int a, int b) => a + b;
}

var math = new MathOperations();
MethodInfo method = typeof(MathOperations).GetMethod("Add");
object result = method?.Invoke(math, new object[] { 5, 3 });
Console.WriteLine(result); // Output: 8

Working with Static Methods

For static methods, pass null as the target object:

class Utility
{
    public static string GetMessage() => "Static method called!";
}

MethodInfo method = typeof(Utility).GetMethod("GetMessage");
object result = method?.Invoke(null, null);
Console.WriteLine(result); // Output: Static method called!

Performance Considerations

  • Reflection is slower than direct method calls because it bypasses compile-time optimizations.
  • Use Delegate.CreateDelegate to improve performance when invoking frequently:
Func<int, int, int> add = (Func<int, int, int>)Delegate.CreateDelegate(
    typeof(Func<int, int, int>),
    typeof(MathOperations).GetMethod("Add")
);
Console.WriteLine(add(5, 3)); // Output: 8

Conclusion

Reflection in C# is a powerful tool for dynamic method invocation. While it introduces some performance overhead, it is invaluable in scenarios requiring runtime flexibility, such as plugins, serialization, and dynamic dependency loading.

0
188

Related

In C#, you can format an integer with commas (thousands separator) using ToString with a format specifier.

int number = 1234567;
string formattedNumber = number.ToString("N0"); // "1,234,567"
Console.WriteLine(formattedNumber);

Explanation:

"N0": The "N" format specifier stands for Number, and "0" means no decimal places. The output depends on the culture settings, so in regions where , is the decimal separator, you might get 1.234.567.

Alternative:

You can also specify culture explicitly if you need a specific format:

using System.Globalization;

int number = 1234567;
string formattedNumber = number.ToString("N0", CultureInfo.InvariantCulture);
Console.WriteLine(formattedNumber); // "1,234,567"
3
388

Slow initial load times can drive users away from your React application. One powerful technique to improve performance is lazy loading - loading components only when they're needed.

Let's explore how to implement this in React.

The Problem with Eager Loading

By default, React bundles all your components together, forcing users to download everything upfront. This makes navigation much quicker and more streamlined once this initial download is complete.

However, depending on the size of your application, it could also create a long initial load time.

import HeavyComponent from './HeavyComponent';
import AnotherHeavyComponent from './AnotherHeavyComponent';

function App() {
  return (
    <div>
      {/* These components load even if user never sees them */}
      <HeavyComponent />
      <AnotherHeavyComponent />
    </div>
  );
}

React.lazy() to the Rescue

React.lazy() lets you defer loading components until they're actually needed:

import React, { lazy, Suspense } from 'react';

// Components are now loaded only when rendered
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const AnotherHeavyComponent = lazy(() => import('./AnotherHeavyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <HeavyComponent />
        <AnotherHeavyComponent />
      </Suspense>
    </div>
  );
}

Route-Based Lazy Loading

Combine with React Router for even better performance:

import React, { lazy, Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./pages/Home'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/dashboard" element={<Dashboard />} />
          <Route path="/settings" element={<Settings />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

Implement these techniques in your React application today and watch your load times improve dramatically!

0
101

Closing a SqlDataReader correctly prevents memory leaks, connection issues, and unclosed resources. Here’s the best way to do it.

Use 'using' to Auto-Close

Using using statements ensures SqlDataReader and SqlConnection are closed even if an exception occurs.

Example

using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine(reader["Username"]);
        }
    } // ✅ Auto-closes reader here
} // ✅ Auto-closes connection here

This approach auto-closes resources when done and it is cleaner and less error-prone than manual closing.

⚡ Alternative: Manually Close in finally Block

If you need explicit control, you can manually close it inside a finally block.

SqlDataReader? reader = null;
try
{
    using SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();
    using SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn);
    reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        Console.WriteLine(reader["Username"]);
    }
}
finally
{
    reader?.Close();  // ✅ Closes reader if it was opened
}

This is slightly more error prone if you forget to add a finally block. But might make sense when you need to handle the reader separately from the command or connection.

0
154