How to pass 2 different types into a function param in c#?

Viewed 90

In c# if I have this

private void Run(Web site) {
    site.BreakRoleInheritance(false, false);
}

private void Run(ListItem folder) {
    folder.BreakRoleInheritance(false, false);
}

How can I instead make 1 function that can accept either Site or Folder?

3 Answers

If Site and Folder are classes that you've created, then you can create a common interface which those classes inherit from. For example:

public interface IBreakable
{
    void break();
}

public class Folder : IBreakable 
{
    public void break() { /* implementation here*/ }
}

public class Site : IBreakable 
{
    public void break() { /* implementation here*/ }
}

Usage

private void Run(IBreakable breakable)
{
    breakable.break();
}

Edit

Here's a solution based on reflection, although this is not ideal.

void Run(object obj)
{
    MethodInfo method = obj.GetType().GetMethod("break");

    if (!(method is null))
    {
        method.Invoke(obj, new object[] {});
    }
}

Given

public class Foo
{
    public void break() {Console.WriteLine("Foo");}
}

public class Bar
{
    public void break() {Console.WriteLine("Bar");}
}

public class Bad
{
    public void NotBreak() {Console.WriteLine("Bad");}
}

Usage

Foo foo = new Foo();
Bar bar = new Bar();
Bad bad = new Bad();

Run(foo);
Run(bar);
Run(bad);

Output

Foo

Bar

As a later answer from @Pedro pointed out, those specific classes derive from a common ancestor, and that would be the preferred option. Assuming you did not have that option:

You can use the C# dynamic type (sorry if that is not the latest doc, I couldn't find a newer one): https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic

Example:

using System;
                
public class Program
{
    public static void Main()
    {
        var foo = new Foo();
        var bar = new Bar();
        DoSomething(foo);
        DoSomething(bar);
    }

    private static void DoSomething<T>(T someObjectWithDoMethod)
    {
        ((dynamic)someObjectWithDoMethod).Do();
    }
}

public class Foo
{
  public void Do() { Console.WriteLine("Foo is doing something"); }
}

public class Bar
{
  public void Do() { Console.WriteLine("Bar is doing something"); }
}

.Net Fiddle: https://dotnetfiddle.net/MShLK5

Based on your comments to other answers, Web and ListItem are types defined in the Microsoft.SharePoint.Client.

Checking the SDK docs, both types derive from SecurableObject where the BreakRoleInheritance method is defined.

That being the case, all you need to do is define one method that takes a SecurableObject object as an input:

public void Run(SecurableObject item)
{
    item.BreakRoleInheritance();
}

And you should be able to pass a Web and a ListItem to this same method.

Related