Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property of generic type in non-generic class

Tags:

c#

generics

Intro

I'm working with the legacy code which contains two classes:

  • I have a class which stores its value of System.Object type. (I named this class as DomainItem)
    • Its Identifier property refers to enum which holds information what a type of DomainItem is (in the context of business domain).
  • There is also a class which stores these items as an Enumerable List. (DomainItems)

What's more:

  • I don't want to change these classes into generic. This code is very sensitive and not covered by tests.
  • In order to get DomainItem, I must get it from DomainItems.Items collection.

Code

The code for classes is equivalent as below:

public class DomainItem
{
    public Identifier Identifier { get; set; } // Readonly in the "real" code
    public object Value { get; set; }
}

public class DomainItems
{
    public IEnumerable<DomainItem> Items { get; set; }
}

The question is

How can I extend these classes using generics, to resolve type of Value property in the compile time. Is it even possible?

Example case might be as following:

DomainItem price = new DomainItem { Value = 25.20d, Identifier = Identifier.Price };
// ....
double priceValue = price.ProperValue; // generic property of type T

Obviously, above code is conceptual and it shows what I want to achieve. Any suggestions how to resolve that? Is it even possible?

Edit

My idea is to create a new IEnumerable<DomainItem<T>> where the collection is populated from non-generic DomainItem objects. Since the type of DomainItem.Value is known, it should be possible to make such collection somehow.

like image 832
Dariusz Woźniak Avatar asked Jan 18 '13 12:01

Dariusz Woźniak


People also ask

Can you have a generic method in a non-generic class?

Yes, you can define a generic method in a non-generic class in Java.

Can a non-generic class inherit a generic class?

Yes you can do it.

Can we have non-generic method in generic class C#?

Yes, There are two level where you can apply generic type . You can apply generic type on Method level as well as Class level (both are optional).

What is the difference between a generic class and a generic method?

A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures. A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.


1 Answers

There's no such thing as a generic property, but you could easily create a generic method:

public T GetValue<T>() { ... }

public void SetValue<T>(T value) { ... }

You could then check typeof(T) within the method to make sure that it was appropriate for your identifier, ideally having made the identifier read-only. (It would be better as a constructor argument - I wouldn't expect it to make any sense to have a domain item whose identifier changed over time.)

Alternatively, you could just make the type of the Value property dynamic instead of object, assuming you're using C# 4+ with .NET 4+. Then your example code would compile - but it would perform an implicit (dynamic) conversion to double at execution time. You wouldn't get much safety there, but it would compile...

like image 53
Jon Skeet Avatar answered Sep 19 '22 07:09

Jon Skeet