简体   繁体   中英

C#, Generic, access to property

I'm using Generic Classes in C# and I wanna access to Text or any other property of the object, how can I do that?

class Methods<T> where T : class
{ 
    bool insertDocument(T content)
    {
        return client.search(content.Text);
    }
}

and i don't want to use Interface

This should work for you.

class Methods<T> where T : class
{ 
    bool insertDocument(T content)
    {
        var textProperty = typeof(T).GetProperty("Text");
        var searchString = textProperty.GetValue(content).ToString();
        return client.search(searchString);
    }
}

I feel that this is an XY problem and that there's a much better way of achieving this, but here goes with a possible solution.

If you want specific Properties work in a generic class you should create a Interface with this Properties and implement this interface in the used classes like:

class Methods<T> where T : class, ITexted
{ 
    bool insertDocument(T content)
    {
        return client.search(content.Text);
    }
}

public interface ITexted
{
    string Text {get; set;}
}

class UsedClass : ITexted
{
   public string Text { get; set; }
}

Edit:

If you don't want to use Interfaces you don't need a generic Class. The you can just use dynamic like:

class Methods
{ 
    bool insertDocument(dynamic content)
    {
        return client.search(content.Text);
    }
}

You can't, you're specifying as the only constraint that 'T' should be a 'class', not all classes have a 'Text' property, so you cannot access that property. You're simply misusing generics (they're not a way to make a single function work with everything, but a way to make a single function work with a subset of object types that share a common behavior that you want to exploit, here you're not specifying a subset, so you end up with a fairly useless 'T' type)

You could do this, although it would be more inefficient:

using System.Linq.Expressions; // include this with your usings at the top of the file

bool insertDocument(T content, Expression<Func<T, string>> textField)
{
    string text = textField.Compile().Invoke(obj);
    return client.search(text);
}

and then use it as so:

class ExampleClass
{
    public string TestProperty {get;set;}
}

-

var example = new ExampleClass() { TestProperty = "hello"; }
bool result = insertDocument(example, e => e.TestProperty);

but you will need to specify the selector each time. At least this way you could keep your code strongly typed.

I'd advise using an interface as per Nikolaus's answer, however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM